左边摇杆控制英雄移动,右边三个按钮分别是三个动画,不用animation,纯代码写
最基础的有三个类,第一个是保存英雄状态的枚举
using UnityEngine;
using System.Collections;
#region StateType 角色的状态类型
/// <summary>
/// 角色的状态类型
/// </summary>
public enum StateType {
None,
Idle,
Run,
Skill1,
Skill2,
Skill3
}
#endregion
第二个基本的类
是一个抽象类,三个状态
using UnityEngine;
using System.Collections;
public abstract class FSMStateAbstract<T> {
public virtual void OnEnter(T user){
}
public virtual void OnStay(T user){
}
public virtual void OnExit(T user){
}
}
第三个也是代码最多的,状态管理器,负责添加状态,改变状态
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FSMStateMgr<T>{
public FSMStateAbstract<T> m_CurrentState;
public FSMStateAbstract<T> m_PreviousState;
public T m_User;
public Dictionary<StateType, FSMStateAbstract<HeroCtr>> m_StaticDic = new Dictionary<StateType, FSMStateAbstract<HeroCtr>>();
public FSMStateMgr(T user){
m_CurrentState = null;
m_PreviousState = null;
m_User = user;
}
public void AddState(StateType stateType){
if (m_StaticDic.ContainsKey (stateType))
return;
switch(stateType)
{
case StateType.None:
break;
case StateType.Idle:
m_StaticDic.Add(stateType, new IdleState());
break;
case StateType.Run:
m_StaticDic.Add(stateType, new RunState());
break;
case StateType.Skill1:
m_StaticDic.Add(stateType, new SkillOneState());
break;
case StateType.Skill2:
m_StaticDic.Add(stateType, new SkillTwoState());
break;
case StateType.Skill3:
m_StaticDic.Add(stateType, new SkillThreeState());
break;
default:
break;
}
}
public void SetCurrentState(StateType stateType){
if (m_StaticDic.ContainsKey (stateType))
return;
if (m_StaticDic.Count > 0)
return;
switch(stateType)
{
case StateType.None:
break;
case StateType.Idle:
m_StaticDic.Add(stateType, new IdleState());
break;
case StateType.Run:
m_StaticDic.Add(stateType, new RunState());
break;
case StateType.Skill1:
m_StaticDic.Add(stateType, new SkillOneState());
break;
case StateType.Skill2:
m_StaticDic.Add(stateType, new SkillTwoState());
break;
case StateType.Skill3:
m_StaticDic.Add(stateType, new SkillThreeState());
break;
default:
break;
}
m_CurrentState = m_StaticDic [stateType] as FSMStateAbstract<T>;
}
public void ChangeState(StateType stateType){
FSMStateAbstract<T> newState = m_StaticDic [stateType] as FSMStateAbstract<T>;
if (newState == null)
return;
if (m_CurrentState != null)
m_CurrentState.OnExit (m_User);
m_PreviousState = m_CurrentState;
m_CurrentState = newState;
m_CurrentState.OnEnter (m_User);
}
public void FSMUpdate(){
if (m_CurrentState != null) {
m_CurrentState.OnStay(m_User);
}
}
}
接下来的基础有了,开始写控制英雄,idle状态,run状态,还有三个方块执行的动画
一共是六个脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HeroCtr : MonoBehaviour {
public EasyJoystick joyStick;
public float moveSpeed = 3f;
public Animation ani;
public CharacterController con;
public bool isGrounded;
public List<string> animationList = new List<string>();
public FSMStateMgr<HeroCtr> m_StateMachine;
public bool isAttack = false;
public Camera cam;
// Use this for initialization
void Start () {
cam = GameObject.Find ("Main Camera").GetComponent<Camera>();
foreach (AnimationState clip in ani) {
animationList.Add(clip.name);
}
StartCoroutine (InitState());
}
void LateUpdate(){
cam.transform.position = transform.position + new Vector3 (0, 3, -5);
cam.transform.LookAt (transform);
}
IEnumerator InitState(){
m_StateMachine = new FSMStateMgr<HeroCtr> (this);
m_StateMachine.SetCurrentState (StateType.Idle);
m_StateMachine.AddState (StateType.Run);
m_StateMachine.AddState (StateType.Skill1);
m_StateMachine.AddState (StateType.Skill2);
m_StateMachine.AddState (StateType.Skill3);
foreach (string aniName in animationList) {
ani[aniName].wrapMode = WrapMode.Once;
}
yield return 0;
}
// Update is called once per frame
void Update () {
m_StateMachine.FSMUpdate ();
DoMove ();
}
public void ClickButton(GameObject obj){
// Debug.Log (obj.name);
StateType stateType = StateType.None;
switch (obj.name)
{
case "Skill1":
stateType = StateType.Skill1;
break;
case "Skill2":
stateType = StateType.Skill2;
break;
case "Skill3":
stateType = StateType.Skill3;
break;
default:
break;
}
// Debug.Log (stateType);
if (isAttack)
return;
m_StateMachine.ChangeState (stateType);
isAttack = true;
}
void DoMove(){
float x = joyStick.JoystickTouch.x;
float z = joyStick.JoystickTouch.y;
Vector3 moveDirection = Vector3.zero;
if (x != 0 || z != 0) {
transform.LookAt (transform.position + new Vector3 (x, 0, z));
moveDirection = transform.TransformDirection (Vector3.forward);
if(!isAttack)
m_StateMachine.ChangeState (StateType.Run);
con.Move (moveDirection * moveSpeed * Time.deltaTime);
} else {
if(!isAttack)
m_StateMachine.ChangeState(StateType.Idle);
}
if (!isGrounded) {
moveDirection += Vector3.down * 9.8f;
}
isGrounded = con.isGrounded;
}
}
idle状态
using UnityEngine;
using System.Collections;
public class IdleState : FSMStateAbstract<HeroCtr> {
public override void OnEnter (HeroCtr user)
{
user.ani.CrossFade ("Idle");
base.OnEnter (user);
}
public override void OnStay (HeroCtr user)
{
if (!user.ani.IsPlaying ("Idle"))
user.ani.CrossFade ("Idle");
base.OnStay (user);
}
public override void OnExit (HeroCtr user)
{
base.OnExit (user);
}
}
run状态
using UnityEngine;
using System.Collections;
public class RunState : FSMStateAbstract<HeroCtr> {
public override void OnEnter (HeroCtr user)
{
user.ani.CrossFade ("Run");
base.OnEnter (user);
}
public override void OnStay (HeroCtr user)
{
if (!user.ani.IsPlaying ("Run"))
user.ani.CrossFade ("Run");
base.OnStay (user);
}
public override void OnExit (HeroCtr user)
{
base.OnExit (user);
}
}
然后是三个方块控制的动画
using UnityEngine;
using System.Collections;
public class SkillOneState : FSMStateAbstract<HeroCtr> {
public override void OnEnter (HeroCtr user)
{
user.ani.CrossFade ("Skill1");
base.OnEnter (user);
Debug.Log ("SkillOne SkillOne");
}
public override void OnStay (HeroCtr user)
{
if (!user.ani.IsPlaying ("Skill1"))
OnExit (user);
base.OnStay (user);
}
public override void OnExit (HeroCtr user)
{
base.OnExit (user);
user.isAttack = false;
}
}
using UnityEngine;
using System.Collections;
public class SkillThreeState : FSMStateAbstract<HeroCtr> {
public override void OnEnter (HeroCtr user)
{
user.ani.CrossFade ("Skill3");
base.OnEnter (user);
Debug.Log ("SkillThree SkillThree");
}
public override void OnStay (HeroCtr user)
{
if (!user.ani.IsPlaying ("Skill3"))
OnExit (user);
base.OnStay (user);
}
public override void OnExit (HeroCtr user)
{
base.OnExit (user);
user.isAttack = false;
}
}
using UnityEngine;
using System.Collections;
public class SkillTwoState : FSMStateAbstract<HeroCtr> {
public override void OnEnter (HeroCtr user)
{
base.OnEnter (user);
user.ani.CrossFade ("Skill2");
Debug.Log ("SkillTwo SkillTwo");
}
public override void OnStay (HeroCtr user)
{
if (!user.ani.IsPlaying ("Skill2"))
OnExit (user);
base.OnStay (user);
}
public override void OnExit (HeroCtr user)
{
base.OnExit (user);
user.isAttack = false;
}
}