好几天没上线了 来刷下存在感~
以前做过一个第一人称射击游戏,记得当时不知道怎么控制怪物的灵活运动,也不懂状态之间的切换,然后就强行堆代码,想想都可怕/(ㄒoㄒ)/~~
后来论坛逛久了对设计模式也就慢慢了解些,23中设计模式,各有优劣吧,毕竟只是一种思想,真正的运用在项目中还是需要自己动脑描述出来
有限状态机的实现有两种选择方式(因为我只知道两种。。。)
1.用枚举enum配合switch语句进行状态之间的选择和切换
2.用多态和虚函数,也就是实现将对象封装在一个抽象类里,然后采用重写的方法实现每一个状态,需要的时候直接调用
接下来就是具体操作了
首先有个功能抽象类
//-------------------------------------------------------------------------------------
//抽象类,定义僵尸的状态之间的链接
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public abstract class BaseState
{
public abstract void AIState(ZombieTest state);
}
还需要有个对外的接口
/// <summary>
/// 僵尸状态的对外接口
/// </summary>
public class ZombieTest : MonoBehaviour
{
public BaseState currentState;
/// <summary>
/// 负责僵尸状态的设置
/// </summary>
/// <param name="state"></param>
public void SetState(BaseState state)
{
currentState = state;
}
/// <summary>
/// 负责僵尸状态的更新
/// </summary>
public void Update()
{
currentState.AIState(this);
}
/// <summary>
/// 返回玩家与僵尸之间的距离
/// </summary>
/// <returns></returns>
public float distance()
{
Vector3 playerVector3 = Player.transform.position;
Vector3 zombieVector3 = zombieTransform.position;
float distanceVector3 = Vector3.Distance(playerVector3, zombieVector3);
return distanceVector3;
}
}
这里我加了个距离 其实想模拟其他情况也是可以的
接下来就是状态的实现
/// <summary>
/// 僵尸最开始时的状态
/// </summary>
public class NormalState : BaseState
{
public ZombieTest zombieTest;
public override void AIState(ZombieTest state)
{
Debug.Log("僵尸目前正在游荡状态,小心!");
}
}
/// <summary>
/// 僵尸追击状态
/// </summary>
public class ChasingState : BaseState
{
private ZombieTest zombieTest;
public override void AIState(ZombieTest state)
{
state.SetState(new AttackState());
Debug.Log("僵尸正在攻击玩家");
}
}
具体想做什么操作 可以在ZombieTest接口内实现功能,然后在具体的状态类里进行验证
我比较喜欢用状态模式实现怪物的状态机,因为一大堆的switch会让我头痛~~~