经过跟队长的一致讨论,决定还是用<有限状态机>来实现怪物的行为逻辑,这样耦合性更低,更好操作。
这次的还是定点巡逻的小怪。
有三个脚本文件,IState作为接口,NewIdleS记录所有存在的状态,NewFSM为有限状态机。
具体实现形式:
1.接口:
public interface NewIstate
{
void OnEnter();
void OnUpdate();
void OnExit();
}
2.记录所有存在的状态:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewIdleSta : NewIstate
{
private NewFSM manager;
private Parameter1 parameter;
private float timer;
//状态机对象
public NewIdleSta(NewFSM manager)
{
this.manager = manager;
this.parameter = manager.parameter;
}
public void OnEnter()
{
parameter.animator.Play("Idle");
}
public void OnUpdate()
{
timer += Time.deltaTime; //计时器
if (timer >= parameter.idleTime)
{
manager.TransitionState(StateType1.Patrol);
}
}
public void OnExit()
{
timer = 0; //清空计时器
}
}
public class PatrolState1 : NewIstate
{
private NewFSM manager;
private Parameter1 parameter;
private int patrolPosition; //切换巡逻点
//状态机对象
public PatrolState1(NewFSM manager)
{
this.manager = manager;
this.parameter = manager.parameter;
}
public void OnEnter()
{
parameter.animator.Play("Walk");
}
public void OnUpdate()
{
manager.FlipTo(parameter.patrolPoints[patrolPosition]);
manager.transform.position = Vector2.MoveTowards(manager.transform.position, parameter.patrolPoints[patrolPosition].position, parameter.moveSpeed * Time.deltaTime);
if (Vector2.Distance(manager.transform.position, parameter.patrolPoints[patrolPosition].position) < .1f)
{
manager.TransitionState(StateType1.Patrol);
}
}
public void OnExit()
{
//下一个巡逻点
patrolPosition++;
//超出数组范围,重新开始巡逻
if (patrolPosition >= parameter.patrolPoints.Length)
{
patrolPosition = 0;
}
}
}
public class ChaseState1 : NewIstate
{
private NewFSM manager;
private Parameter1 parameter;
//状态机对象
public ChaseState1(NewFSM manager)
{
this.manager = manager;
this.parameter = manager.parameter;
}
public void OnEnter()
{
}
public void OnUpdate()
{
}
public void OnExit()
{
}
}
public class AttackState1 : NewIstate
{
private NewFSM manager;
private Parameter1 parameter;
//状态机对象
public AttackState1(NewFSM manager)
{
this.manager = manager;
this.parameter = manager.parameter;
}
public void OnEnter()
{
}
public void OnUpdate()
{
}
public void OnExit()
{
}
}
3.有限状态机;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public enum StateType1
{
Idle, Patrol, Chase, Attack
}
[Serializable] //序列化此类
//敌人参数
public class Parameter1
{
public int health;
public float moveSpeed;
public float chaseSpeed;
public float idleTime;
public Transform[] patrolPoints;
public Transform[] chasePoints;
public Animator animator;
}
public class NewFSM : MonoBehaviour
{
//声明当前状态
private NewIstate currentState;
public Parameter1 parameter;
private Dictionary<StateType1, NewIstate> states = new Dictionary<StateType1, NewIstate>();
void Start()
{
//增加字典键值对
states.Add(StateType1.Idle, new NewIdleSta(this));
states.Add(StateType1.Patrol, new PatrolState1(this));
states.Add(StateType1.Chase, new ChaseState1(this));
states.Add(StateType1.Attack, new AttackState1(this));
//初始状态
TransitionState(StateType1.Idle);
parameter.animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
currentState.OnUpdate();
}
//切换状态
public void TransitionState(StateType1 type)
{
if (currentState != null)
currentState.OnExit();
currentState = states[type]; //字典找到相应的状态类
currentState.OnEnter();
}
//更改朝向
public void FlipTo(Transform target)
{
if (target != null)
{
if (transform.position.x >= target.position.x)
{
transform.localScale = new Vector3(-1, 1, 1);
}
else if (transform.position.x < target.position.x)
{
transform.localScale = new Vector3(1, 1, 1);
}
}
}
}