public enum FsmState
{
none,
idle,
run,
skill1,
skill2,
skill3,
skill4,
death
}
FsmStateBase基类
public class FsmStateBase<StateOwner > {
public virtual void OnEnter (StateOwner owner){}
public virtual void OnStay(StateOwner owner){}
public virtual void OnExit(StateOwner owner){}
}
FsmIdleState
public class FsmIdleState :FsmStateBase<PlayerContrl>
{
public override void OnEnter (PlayerContrl owner)
{
owner.ani.CrossFade ("stand");
}
public override void OnStay (PlayerContrl owner)
{
if (!owner.ani.IsPlaying("stand"))
{
owner.ani.CrossFade ("stand");
}
}
public override void OnExit (PlayerContrl owner)
{
}
}
FsmRunState
public class FsmRunState :FsmStateBase<PlayerContrl> {
public override void OnEnter (PlayerContrl owner)
{
owner.ani.CrossFade ("run");
}
public override void OnStay (PlayerContrl owner)
{
if (!owner.ani.IsPlaying("run"))
{
owner.ani.CrossFade ("run");
//OnEnter();
}
}
public override void OnExit (PlayerContrl owner)
{
}
}
FsmSkill1State
public class FsmSkill1State :FsmStateBase<PlayerContrl> {
public override void OnEnter (PlayerContrl owner)
{
owner.ani.CrossFade ("attack");
}
public override void OnStay (PlayerContrl owner)
{
if (!owner.ani.IsPlaying("attack"))
{
OnExit (owner);
//OnEnter();
}
}
public override void OnExit (PlayerContrl owner)
{
owner.isAttack = false;
}
}
FsmRunState 状态总管理类
public class FsmStateManager <StateOwner> {
public FsmStateBase<StateOwner> oldState; //指动画的上一个状态
public FsmStateBase<StateOwner> currentState; //当前状态
StateOwner owner; //指定一个实际的拥有者
public Dictionary<FsmState,FsmStateBase<PlayerContrl>> stateDic = new Dictionary<FsmState, FsmStateBase<PlayerContrl>> ();
public FsmStateManager(StateOwner _owner)
{
oldState = null;
currentState = null;
owner = _owner;
}
public void SetDeafultState(FsmState statetype) //设置默认状态
{
if (stateDic.ContainsKey (statetype)) {
return;
}
switch (statetype) {
case FsmState.none:
break;
case FsmState.idle:
stateDic.Add (statetype, new FsmIdleState ());
break;
case FsmState.run:
stateDic.Add (statetype, new FsmRunState ());
break;
case FsmState.skill1:
stateDic.Add (statetype, new FsmSkill1State ());
break;
case FsmState.skill2:
stateDic.Add (statetype, new FsmSkill2State ());
break;
case FsmState.skill3:
stateDic.Add (statetype, new FsmSkill3State ());
break;
case FsmState.skill4:
stateDic.Add (statetype, new FsmSkill4State ());
break;
case FsmState.death:
break;
default:
break;
}
currentState = stateDic [statetype] as FsmStateBase<StateOwner>;
}
public void SetInitState(FsmState statetype) //初始化所有状态
{
if (stateDic .Count == 0) //为空,则代表未设置默认状态
{
return;
}
if (stateDic .ContainsKey(statetype)) //已经包含此状态,不用添加
{
return;
}
switch (statetype)
{
case FsmState.none:
break;
case FsmState.idle:
stateDic.Add (statetype, new FsmIdleState ());
break;
case FsmState.run:
stateDic.Add (statetype, new FsmRunState ());
break;
case FsmState.skill1:
stateDic.Add (statetype, new FsmSkill1State ());
break;
case FsmState.skill2:
stateDic.Add (statetype, new FsmSkill2State ());
break;
case FsmState.skill3:
stateDic.Add (statetype, new FsmSkill3State ());
break;
case FsmState.skill4:
stateDic.Add (statetype, new FsmSkill4State ());
break;
case FsmState.death:
break;
default:
break;
}
}
public void ChangeState(FsmState statetype) //更换状态
{
if (currentState != null) //退出当前状态
{
currentState.OnExit (owner);
}
if (!stateDic.ContainsKey(statetype)) //如果不存在此状态,则退出,不能更换
{
return;
}
oldState = currentState; //当前状态改为上一状态
currentState = stateDic[statetype] as FsmStateBase<StateOwner>; //将更换状态 设置为当前状态
currentState.OnEnter (owner);
}
public void UpdateState() //保持当前状态
{
if (currentState !=null)
{
currentState.OnStay (owner);
}
}
}
PlayerContrl 角色管理类调用状态管理类
public class PlayerContrl : MonoBehaviour {
public bool InRange = false;
public Animation ani;
public FsmStateManager<PlayerContrl> stateManager; //管理类对象
public EasyJoystick myjoystick;
private CharacterController characterctr;
public float speed = 100f;
public Transform skill;
public bool isAttack= false;
public GameObject particleEffect;
void Start ()
{
myjoystick = GameObject.Find ("New joystick").GetComponent<EasyJoystick> ();
ani = GetComponent<Animation> ();
characterctr = GetComponent <CharacterController> ();
StartCoroutine (InitState ());//初始化动画信息
//AddEventBtnOnclick ();
//粒子的预热 状态设置为隐藏,实例化粒子特效后,粒子脚本已经完成初始化工作了,也就是Awake 和 OnEnable方法
// particleEffect = Resources.Load ("Effect_skill_banyuezhan_Hit")as GameObject;
// particleEffect = Instantiate (particleEffect);
//
// particleEffect.transform.position = transform.position;
// particleEffect.AddComponent<ParticleManager> ();
// particleEffect.SetActive (false);
}
void Update()
{
PlayerMove ();
stateManager.UpdateState ();
if (Input.GetKey(KeyCode.Space))
{
this.transform.position +=new Vector3 (0,1,0);
}
}
IEnumerator InitState()
{
foreach (AnimationState state in ani)
{
state.wrapMode = WrapMode.Once; //更改角色的所有动画模式为单次
}
stateManager = new FsmStateManager<PlayerContrl> (this);
stateManager.SetDeafultState (FsmState.idle);
stateManager.SetInitState(FsmState.run);
stateManager.SetInitState(FsmState.skill1);
stateManager.SetInitState(FsmState.skill2);
stateManager.SetInitState(FsmState.skill3);
stateManager.SetInitState(FsmState.skill4);
stateManager.SetInitState(FsmState.death);
yield return 0;
}
void PlayerMove()
{
if (myjoystick.JoystickTouch != Vector2.zero)
{
stateManager.ChangeState (FsmState.run);
transform.LookAt (transform.position + new Vector3 (myjoystick.JoystickTouch.x,0,myjoystick.JoystickTouch.y));
Vector3 dir = new Vector3 (myjoystick.JoystickTouch.x, 0, myjoystick.JoystickTouch.y);
characterctr.SimpleMove (dir * speed *Time.deltaTime);
}
else
{
if (!isAttack)
{
stateManager.ChangeState (FsmState.idle);
}
}
}
public void SkillEvent(string skillName)
{ isAttack = true;
switch (skillName)
{
case "Skill1":
stateManager.ChangeState (FsmState.skill1);
if (InRange) //在攻击范围内,调用方法,怪物减血
{ Debug.Log("在攻击范围内");
Guaiwu._instance.GetHurt (10);
}
break;
case "Skill2":
stateManager.ChangeState (FsmState.skill2);
//particleEffect.SetActive (true);
if (InRange) //在攻击范围内,调用方法,怪物减血
{
Guaiwu._instance.GetHurt (15);
}
break;
case "Skill3":
stateManager.ChangeState (FsmState.skill3);
if (InRange) //在攻击范围内,调用方法,怪物减血
{
Guaiwu._instance.GetHurt (20);
}
break;
case "Skill4":
stateManager.ChangeState (FsmState.skill4);
if (InRange) //在攻击范围内,调用方法,怪物减血
{
Guaiwu._instance.GetHurt (25);
}
break;
default:
break;
}
}
}