目录
7、UI管理和游戏管理并实现阳光数量显示
新建 UIManager.cs脚本,由于它是UI的管理类,所以使用单例模式,添加代码
using System;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
public static UIManager instance;
private Text sunNumText;
private void Awake()
{
instance = this;
}
private void Start()
{
sunNumText = transform.Find("MainPanel/SunNumText").GetComponent<Text>();
}
// 更新阳光数字
public void UpdateSunNum(int num)
{
sunNumText.text = num.ToString();
}
}
把该脚本附加到Canvas上
以上代码写了阳光显示文本UI的功能,如何将数字传给UIManager并显示,此时需要一个游戏的全局管理类,也就是GameManager.cs,新建一个对象GameManager,并将脚本附加上去
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
// 阳光的数量
private int sunNum;
private void Awake()
{
instance = this;
}
public int SunNum
{
get => sunNum;
set
{
sunNum = value;
UIManager.instance.UpdateSunNum(sunNum);
}
}
private void Update()
{
SunNum += 1;
}
}
在Update函数中模拟一下当阳光数增加时UI的变化
然后将Update函数删除(测试用),添加Start函数,初始化SunNum=100
8、阳关点击事件实现,并累加阳光值
当点击阳光时触发,所以需要写一个OnMouseDown函数,前提是在阳光预制体上添加一个碰撞器才能触发
在Sun.cs中更新代码
……
public class Sun : MonoBehaviour
{
……
// 鼠标点击阳光时触发增加阳光数量,该函数需要碰撞器才有效果
private void OnMouseDown()
{
GameManager.instance.SunNum += 50;
}
……
}
测试
9、点击后阳光飘到阳光UI处消失
既然要移动到阳光UI处,所以需要得到它的世界坐标,在UIManager.cs更新代码
using System;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
public static UIManager instance;
private Text sunNumText;
private void Awake()
{
instance = this;
// 可能阳光初始值设置后,sunNumText还未获取,所以放在Awake里
sunNumText = transform.Find("MainPanel/SunNumText").GetComponent<Text>();
}
private void Start()
{
}
// 更新阳光数字
public void UpdateSunNum(int num)
{
sunNumText.text = num.ToString();
}
// 获取阳光数量文本的世界坐标
public Vector3 GetSunNumTextPos()
{
// transform.position是个结构体,修改pos.x实际上是对position的复制体修改,所以如果修改最后还要transform.position = pos;
// 这里得到的是阳光UI文本的屏幕坐标,之所以有Z轴,是用来区分摄像机不同视角下的屏幕坐标
return sunNumText.transform.position;
}
}
将屏幕坐标转化为世界坐标后,就启用协程,获得阳光和UI的方向向量,然后移动过去,根据距离判断游戏销毁,在Sun.cs中更新代码:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sun : MonoBehaviour
{
……
// 鼠标点击阳光时触发增加阳光数量,该函数需要碰撞器才有效果
private void OnMouseDown()
{
GameManager.instance.SunNum += 50;
// 将屏幕坐标转化为世界坐标
Vector3 sunNumPos = Camera.main.ScreenToWorldPoint(UIManager.instance.GetSunNumTextPos());
// 由于Z不可预测,把它变为0,注意最好别sunNumPos.z=0,应该改变的不是sunNumPos本身的值
sunNumPos = new Vector3(sunNumPos.x, sunNumPos.y, 0);
FlyAnimation(sunNumPos);
}
private void FlyAnimation(Vector3 pos)
{
StartCoroutine(DoFly(pos));
}
IEnumerator DoFly(Vector3 pos)
{
// 获得阳光到阳光文本的方向向量
// Vector3.normalized的特点是当前向量是不改变的并且【返回】一个新的规范化的向量(长度为1);
// Vector3.Normalize的特点是改变当前向量,然后当前向量长度是1
Vector3 direction = (pos - transform.position).normalized;
while (Vector3.Distance(pos, transform.position) > 0.5f)
{
yield return new WaitForSeconds(0.01f);
transform.Translate(direction); // 往这个方向移动
}
DestroySun();
}
……
}