900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 游戏开发中的有限状态机(FMS)

游戏开发中的有限状态机(FMS)

时间:2023-09-11 08:22:45

相关推荐

游戏开发中的有限状态机(FMS)

游戏开发中的有限状态机(FMS)

这个可以看成是一个AI模板,无论大小游戏中敌人以及一些NPC都是是游戏中不可或缺的一些元素,他们AI的好坏会严重影响我们的游戏体验,而有限状态机可以制作一些简单的AI,并且可以保持逻辑的有序性以及代码的可阅读性。

用干净的代码实现一些基本功能。

创建一个最基本的接口,所有状态都基于这个接口

public interface IState {void OnEnter();//进入状态void OnUpdate();//状态进行中void OnExit();//离开状态}

创建几个基本的状态作为示范

Idle状态

public class IdleState : IState{private FMS fms;private Character character;private float timer;public IdleState(FMS fms,Character character)//在状态机中实例化的时候可以指定是哪个状态机与属性类{this.fms = fms;this.character = character;}public void OnEnter(){fms.PlayAnimation("Idle");}public void OnExit(){timer = 0;}public void OnUpdate(){timer += Time.deltaTime;if (timer > 3){fms.SetState(Enum.StateType.walk);}}}

Walk状态

public class WalkState : IState{private FMS fms;private Character character;public WalkState(FMS fms, Character character){this.fms = fms;this.character = character;}public void OnEnter(){fms.PlayAnimation("Walking");}public void OnExit(){character.StopMove();fms.positionIndex++;if (fms.positionIndex > fms.position.Length-1)fms.positionIndex = 0;character.SetTarget(fms.position[fms.positionIndex]);}public void OnUpdate(){if (character.ToWard()){if (character.isAttack)fms.SetState(Enum.StateType.attack);elsefms.SetState(Enum.StateType.idle);}}}

Attack状态

public class AttackState : IState{private FMS fms;private Character character;public AttackState(FMS fms, Character character){this.fms = fms;this.character = character;}public void OnEnter(){fms.PlayAnimation("Attacking");}public void OnExit(){}public void OnUpdate(){if (!character.isAttack)fms.SetState(Enum.StateType.idle);}}

状态机的实现

public class FMS : MonoBehaviour{private IState currentState;private Dictionary<Enum.StateType, IState> states = new Dictionary<Enum.StateType, IState>();private Character character;private Animator animator;public Transform[] position;public int positionIndex = 0;private void Awake(){character = GetComponent<Character>();animator = GetComponent<Animator>();}private void Start(){states.Add(Enum.StateType.idle, new IdleState(this,character));states.Add(Enum.StateType.walk, new WalkState(this,character));states.Add(Enum.StateType.attack, new AttackState(this,character));SetState(Enum.StateType.idle);character.SetTarget(position[positionIndex]);}private void Update(){currentState.OnUpdate();}public void SetState(Enum.StateType stateType)//设置状态,如果当前状态不为空,调用当前状态的离开方法,设置当前状态,调用当前状态的进入方法{if (currentState != null){currentState.OnExit();}currentState = states[stateType];currentState.OnEnter();}public void PlayAnimation(string name){animator.Play(name);}private void OnTriggerEnter2D(Collider2D collision){if (collision.tag != this.tag){character.isAttack = true;character.SetEenemy(collision.gameObject.GetComponent<Character>());SetState(Enum.StateType.attack);}}}

基本属性类的实现

public class Character : MonoBehaviour{private Animator animator;private new Rigidbody2D rigidbody2D;[SerializeField]private Transform target;[SerializeField]private float moveSpeed;public bool isAttack = false;[SerializeField] private float hp;[SerializeField] private float atk;[SerializeField] private float df;private Character enmemyCharacter;//敌人的属性脚本void Start(){animator = GetComponent<Animator>();rigidbody2D = GetComponent<Rigidbody2D>();}public bool ToWard()//移向目标{if (Vector2.Distance(target.position, transform.position) < 0.1f){return true;}if (target.position.x < transform.position.x){transform.localScale = new Vector3(-1,1);}else{transform.localScale = new Vector3(1, 1);}rigidbody2D.velocity=((target.position-transform.position).normalized)*moveSpeed;return false;}public void StopMove(){rigidbody2D.velocity = Vector2.zero;}public void SetTarget(Transform target){this.target = target;}public void SetEenemy(Character character){enmemyCharacter = character;}public void GetDamage(float atk){hp -= atk - df;}public void Attack(){enmemyCharacter.GetDamage(atk);}}

通过FMS与Character这两个脚本便可以实现一些战斗功能,具体效果如下:

只能放动态图勉强看一下

双方会走向绿点在过程中遭遇然后战斗。

这样简单的有限状态机就完成了,大家可以根据需求完善脚本。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。