Unity实战案例全解析:PVZ 植物卡片状态分析
Siki学院2023的PVZ免费了,学一下也坏
卡片状态
卡片可以有三种状态:
1.阳光足够,(且cd好了可以种植)
2.阳光不够,(cd?好了:没好 (三目运算符))
3.开始转cd,(被种下)
状态切换是单向循环的,只有a到b,没有a到c所以不会互相干扰,所以上面括号内的内容可以不用考虑
转换状态触发条件
因为教程中使用的是枚举配合Switch切换状态
public class ControlState : MonoBehaviour
{
public enum Card_State
{
//准备就绪
E_Ready,
//Cd
E_Cd,
//cd结束等待阳光
E_WaitingSun
}
//三种状态的对象
public GameObject Light;
public GameObject WaitSun;
public Image LayerMask;
Card_State state;
//计时器变量
public float ReadNeedTime = 2;
public float CdTime = 0;
//需要阳光数
public int needSunPoint = 50;
private void Awake() {
//初始状态表现一下Cd冷却
state = Card_State.E_Cd;
}
private void Update() {
switch (state) {
case Card_State.E_Ready:
ReadyUpdate();
break;
case Card_State.E_Cd:
CDUpdate();
break;
case Card_State.E_WaitingSun:
WaitingSunUpdate();
break;
default:
throw new System.NotImplementedException("未正确返回枚举类型");
}
}
/// <summary>
/// 阳光不够就切换回等待状态
/// </summary>
public void ReadyUpdate()
{
if (needSunPoint > SunManger.Instance.SunPoint) {
Translate2WaitSun();
}
}
/// <summary>
/// 转cd,如果cd转完了则转到等待阳光阶段
/// </summary>
public void CDUpdate()
{
//计时器变0将图片设置为WaitingSun状态
CdTime += Time.deltaTime;
LayerMask.fillAmount = (ReadNeedTime - CdTime) / ReadNeedTime;
if (CdTime>ReadNeedTime)
{
Translate2WaitSun();
}
}
/// <summary>
/// 阳光足够则转为准备好的阶段
/// </summary>
public void WaitingSunUpdate() {
if (needSunPoint <= SunManger.Instance.SunPoint)
{
Translate2Ready();
}
}
让我想想,从难度低到难度高,还有几种方式可以切换状态
1.if else 我以切换条件定义一堆变量可以实现条件切换
2.事件,写了这么多函数是否可以用Unity.Event的配合UGUI来切换呢?有待考究
胡说但是说不定可行:3.状态机 4.行为树
转换状态中要处理的逻辑
/// <summary>
/// 转换方法:2WaitSun
/// </summary>
public void Translate2WaitSun()
{
state = Card_State.E_WaitingSun;
LayerMask.gameObject.SetActive(false);
Light.SetActive(false);
WaitSun.SetActive(true);
//重置计时器
CdTime = 0;
}
/// <summary>
/// 转换方法:2Ready
/// </summary>
public void Translate2Ready()
{
state = Card_State.E_Ready;
LayerMask.gameObject.SetActive(false);
Light.SetActive(true);
WaitSun.SetActive(false);
}
/// <summary>
/// 转换方法:2Cd
/// </summary>
public void Translate2Cd() {
state = Card_State.E_Cd;
LayerMask.gameObject.SetActive(true);
Light.SetActive(false);
WaitSun.SetActive(true);
}
/// <summary>
/// Ready下被点击将会进入cd
/// </summary>
public void OnClick()
{
//阳光检查
if (needSunPoint > SunManger.Instance.SunPoint)
return;
//TODO:被种植
//转入cd状态
Translate2Cd();
}
}