今天学习制作了一个简单的抽卡功能,学习结束后目录结构如下:
.mate文件是unity生成的配置文件,不用管
制作第一张卡片
- 创建一个空物体,改名为Card。
- 在Card下挂载以下UI组件:
- 编写数据脚本并挂载,unity采用c#作为脚本语言。
3-1. 首先定义一个卡牌类,定义卡牌上通用的属性
public class Card {
// 卡牌id
public int id;
// 卡牌名称
public string cardName;
// 卡牌描述
public string direction;
// 构造函数
public Card(int _id, string _cardName, string _direction){
this.id = _id;
this.cardName = _cardName;
this.direction = _direction;
}
}
3-2. 定义一个怪物卡类,继承自卡牌类,添加独有的攻击力,最大生命和当前生命。同时定义一个魔法卡类,后续有魔法卡的专有属性时方便添加。
public class MonsterCard: Card {
// 攻击力
public int attack;
// 当前生命值
public int healthPoint;
// 最大生命值
public int healthPointMax;
// 使用base调用父类的构造函数
public MonsterCard(int _id, string _cardName, string _direction,int _attack, int _healthPointMax):base(_id, _cardName, _direction)
{
this.attack = _attack;
this.healthPointMax = _healthPointMax;
this.healthPoint = _healthPointMax;
}
}
public class SpellCard: Card {
// public string effect;
public SpellCard(int _id, string _cardName, string _direction):base(_id, _cardName, _direction)
{
// this.effect = _effect;
}
}
- 将数据类与视图想关联
定义一个脚本用于呈现数据,命名为CardDisPlay。
在类中定义相关的UI属性,并用Card中的数据对UI属性进行赋值。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CardDisplay : MonoBehaviour
{
// UI相关的属性
public Text nameText;
public Text attackText;
public Text healthText;
// public Text effectText;
public Text directionText;
public Image backgroundImage;
public Card card;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void ShowCard(){
nameText.text = card.cardName;
directionText.text = card.direction;
if (card is MonsterCard)
{
var monster = card as MonsterCard;
attackText.text = monster.attack.ToString();
healthText.text = monster.healthPoint.ToString();
// effectText.gameObject.SetActive(false);
}
else if (card is SpellCard)
{
var spell = card as SpellCard;
// effectText.text = spell.effect;
attackText.gameObject.SetActive(false);
healthText.gameObject.SetActive(false);
}
}
}
- 将定义好的脚本组件挂载道卡片上,并将组件的属性与对应的UI关联。
- 将做好的卡片保存为预制体。
抽卡场景
场景
unity通过划分场景来对游戏的页面进行划分,场景文件的后缀名为.sence
。
卡牌数据读取
定义一个空物体命名为CardStore,并定义一个名为CardStore的脚本文件,用来读取卡牌数据。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CardStore : MonoBehaviour
{
// 定义一个文本资源
public TextAsset cardDate;
// 定义链表,跟数组对比的好处是它不限制数量,添加和删除十分方便
public List<Card> cardList = new List<Card>();
// Start is called before the first frame update
void Start()
{
LoadCardDate();
}
// Update is called once per frame
void Update()
{
}
public void LoadCardDate(){
string[] dateRow = cardDate.text.Split('\n');
foreach (var row in dateRow)
{
string[] rowArray = row.Split(',');
if(rowArray[0] == "#"){
continue;
}
else if(rowArray[0] == "monster"){
// 新建怪兽卡
int id = int.Parse(rowArray[1]);
string name = rowArray[2];
string direction = rowArray[3];
int atk = int.Parse(rowArray[4]);
int health = int.Parse(rowArray[5]);
MonsterCard monsterCard = new MonsterCard(id,name,direction,atk,health);
cardList.Add(monsterCard);
// Debug.Log("读取到怪兽卡:" + monsterCard.cardName);
}
else if(rowArray[0] == "spell"){
// 新建魔法卡
int id = int.Parse(rowArray[1]);
string name = rowArray[2];
string direction = rowArray[3];
string effect = rowArray[4];
SpellCard spellcard = new SpellCard(id,name,direction);
cardList.Add(spellcard);
// Debug.Log("读取到魔法卡:" + spellcard.cardName);
}
}
}
// 返回数据中的随机一张卡,后面抽卡时后用到
public Card RandomCard(){
Card card = cardList[Random.Range(0,cardList.Count)];
return card;
}
}
将脚本挂载到CardStore这个物体上,并将文本数据关联起来,就可以进行读取。
卡池
定义一个空物体并添加网格布局组件,用于展示抽到的卡。
抽卡脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OpenPackage : MonoBehaviour
{
public GameObject cardPrefeb;
CardStore CardStore;
public GameObject cardpool;
// Start is called before the first frame update
void Start()
{
CardStore = GetComponent<CardStore>();
}
// Update is called once per frame
void Update()
{
}
public void OnClickOpen(){
for (int j = 0; j < cardpool.transform.childCount; j++) {
Destroy (cardpool.transform.GetChild(j).gameObject);
}
for(int i = 0; i < 5; i++){
// 使用预制体生成一个游戏对象
GameObject newCard = GameObject.Instantiate(cardPrefeb, cardpool.transform);
// 在这个预制体上挂载一个卡片属性,用来指代这张卡本身
// GetComponent这个函数用来获取当前物体上的其他组件
newCard.GetComponent<CardDisplay>().card = CardStore.RandomCard();
newCard.GetComponent<CardDisplay>().ShowCard();
// Debug.Log($"执行了");
}
}
}
按钮组件
按钮组件也是UI组件的一种,可以选择编写的组件中的方法作为点击事件。
将相关的物体关联好,这样在点击抽卡按钮时,就会随机在页面上展示5张卡片。