功能实现:
制作游戏中的多种道具,如金币,血瓶等,
各种道具具有的外观和功能都不一样,
通过代码方式往地图中随机生成这些道具,
通过管理器进行管理,
保证生成的所有道具都不能重叠到一起,
玩家碰到道具可以获取,道具消失
功能一:道具的随机生成
思路:
先传入需要生成的预设体对象,存到GameObject[] itemPrefabs数组中。
GameObject[] itemPrefabs;
void Start()
{
itemPrefabs = new GameObject[3];
itemPrefabs[0] = Resources.Load<GameObject>("Prefabs/Coin");
itemPrefabs[1] = Resources.Load<GameObject>("Prefabs/Equip");
itemPrefabs[2] = Resources.Load<GameObject>("Prefabs/Hp");
}
由于金币的生成都是由ItemManager进行管理,因此需要在start()函数里写,在游戏运行前一帧生成金币。
首先定义两个物体之间的距离,以及跳出循环的条件:maxNum (最大生成道具数量)数量
public float distance=1.0f;//物体和物体之间的距离(默认1米)
public int maxNum = 20;//最大生成道具数量
生成一定数量的金币肯定得用到循环, 我们这里选择使用while循环。
定义随机生成道具的坐标x y z:
while (true)
{
float x = Random.Range(-9.0f, 9.0f);
float y = 0.5f;
float z = Random.Range(-9.0f, 9.0f);
}
将坐标赋予 ->一个新的三维向量randPosition
Vector3 randPosition = new Vector3(x,y,z);//世界坐标
跟之前生成的道具进行距离比较,遍历每个道具的transform组件里面的position,符合条件的话随机一个道具加入到ItemManager里。
其中比较距离是使用向量相减的方式:
这里我们要求出ab的距离是否小于1 ,小于则舍弃,大于等于则添加。
用向量ob - 向量oa 可以得出向量ab ,进行对ab长度的判断。
bool canAdd = true;//能否添加道具
foreach (Transform item in transform)
{
Vector3 curItemPos = item.position;//当前孩子的世界坐标
Vector3 offset = curItemPos - randPosition;//获得两个向量的相对向量
float curDis = offset.magnitude;//向量长度
if(curDis<distance)
{
canAdd = false;
break;
}
}
if(canAdd)
{
int index = Random.Range(0, itemPrefabs.Length);
GameObject goItem = Instantiate<GameObject>(itemPrefabs[index]);//创建实例对象(克隆),生成到场景中
goItem.transform.position = randPosition;//对象的位置进行赋值
goItem.transform.parent = transform;//把生成的对象放到父物体下面(重要)
if(transform.childCount>=maxNum)
{
break;
}
}
以上实现了小球的随机生成功能;
功能2:在小球触碰道具时,实现“加分”的效果
既然要实现加分 ,首先先在unity创建一个空的GameObject起名叫UI 用来操作游戏界面的展示的游戏对象 :
父物体是文字,子物体是数字,我们要实现数字的改变
在UI游戏对象下挂载一个UI脚本 将三个Text对象存入
public Text txtCoin;
public Text txtHp;
public Text txtEquip;
void Start()
{
//比较安全的写法
GameObject goTxtCoin = GameObject.Find("TxtCoin");
if(goTxtCoin)
{
txtCoin=goTxtCoin.GetComponent<Text>();
}
//简易写法
txtHp = GameObject.Find("TxtHp").GetComponent<Text>();
txtEquip = GameObject.Find("TxtEquip").GetComponent<Text>();
}
updateCoin(),updateHp(),updateEquip()三个函数在UI里面实现数字的改变
public void updateCoin(int num)
{
txtCoin.text = num.ToString();
}
public void updateHp(int num)
{
txtHp.text = num.ToString();
}
public void updateEquip(int num)
{
txtEquip.text = num.ToString();
}
既然是要实现小球吃金币加分的效果,代码只能写在小球或者金币上,这次我们写在小球上:
需要分辨道具是金币,装备还是血瓶, 将每个游戏对象身上添加一个tag ,
用CompareTag()进行标签比较。
需要跟UI进行交互,创建UI对象:
UI gameUI;
分别定义三个道具的字段及属性:
int coinNum;//金币数量
public int CoinNum//通过属性控制字段
{
get { return coinNum; }
set
{
//数据发生变化
coinNum = value;
//更新UI(直接通信)
if(!gameUI)
{
gameUI=GameObject.Find("UI").GetComponent<UI>();
}
gameUI.updateCoin(coinNum);
}
}
int hpNum;//hp数量
public int HpNum
{
get { return hpNum; }
set
{
hpNum = value;
//更新UI
if (!gameUI)
{
gameUI = GameObject.Find("UI").GetComponent<UI>();
}
gameUI.updateHp(hpNum);
}
}
int equipNum;//装备数量
public int EquipNum
{
get { return equipNum; }
set
{
equipNum = value;
//更新UI
if (!gameUI)
{
gameUI = GameObject.Find("UI").GetComponent<UI>();
}
gameUI.updateEquip(equipNum);
}
}
定义触发器在小球触碰道具时道具的数量+1并摧毁道具
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Coin"))//碰到金币
{
CoinNum++;
}
else if (other.CompareTag("Hp"))
{
HpNum++;
}else if(other.CompareTag("Equip"))
{
EquipNum++;
}
Destroy(other.gameObject);
}
实现效果如下: