FSM 旧版动画控制类,技能特效,冷却时间

动画状态机

FsmState枚举

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;
        }

    }


}

技能按钮冷却方法1

public class SkillCd : MonoBehaviour {

    public float skillCdTime = 0;
    public float currentTime =0;
    private UISprite fg;
    private UILabel  timelabel;
    private GameObject player;

    public PosType posType = PosType.Basic;
    private PlayerAnimation playerAnimation;

    void Start ()
    {
        fg = transform.Find ("FG").GetComponent<UISprite>();
        timelabel = transform.Find ("Label").GetComponent<UILabel> ();
        player = GameObject.FindWithTag ("Player");
        playerAnimation = player.GetComponent<PlayerAnimation> ();
    }

    void Update()
    {
        if (fg.fillAmount==1) 
            return;
        currentTime -= Time.deltaTime;

        timelabel.text = currentTime.ToString ("0");
        fg.fillAmount = 1 / skillCdTime * (skillCdTime - currentTime);
        if (currentTime <=0) 
        {
            GetComponent<Collider> ().enabled = true;
            timelabel.text = "";
        }

    }

    void OnClick()
    {
        GetComponent<Collider> ().enabled = false;
        timelabel.text = skillCdTime.ToString ();
        currentTime = skillCdTime;
        fg.fillAmount = 0;
    //    player.SendMessage ("SkillEvent", this.name,SendMessageOptions.DontRequireReceiver);   方法1

    }
    void OnPress(bool isPress)  //在控制面板修改不同按钮的posType的类型   方法2
    {
        playerAnimation.OnAttackButton (isPress,posType);
    }

}

public enum PosType  {

    Basic,One=1,Two=2,Three=3

}

技能按钮冷却方法2

public class SkillCd : MonoBehaviour {


	public float skillCdTime = 0;
	public float currentTime =0;
	private UISprite fg;
	private UILabel  timelabel;
	private GameObject player;

	void Start ()
	{
		fg = transform.Find ("FG").GetComponent<UISprite>();
		timelabel = transform.Find ("Label").GetComponent<UILabel> ();
		player = GameObject.Find ("player");
	}

	void Update()
	{
		if (fg.fillAmount==1) 
			return;
		currentTime -= Time.deltaTime;

		timelabel.text = currentTime.ToString ("0");
		fg.fillAmount = 1 / skillCdTime * (skillCdTime - currentTime);
		if (currentTime <=0) 
		{
			GetComponent<Collider> ().enabled = true;
			timelabel.text = "";
		}

	}

	void OnClick()
	{
		GetComponent<Collider> ().enabled = false;
		timelabel.text = skillCdTime.ToString ();
		currentTime = skillCdTime;
		fg.fillAmount = 0;
		player.SendMessage ("SkillEvent", this.name,SendMessageOptions.DontRequireReceiver);


	}
}

控制粒子播放时间,播放完最长的时间后隐藏

public class ParticalManager : MonoBehaviour {

    private ParticleSystem[] particleEffects;  //粒子特效的集合
    private float effectTime=0; //粒子特效的生成时间
    private GameObject targert;

    //激活特效的游戏对象时来播放粒子特效
    void OnEnable()
    {
        targert = GameObject.FindWithTag ("Player");
        //transform.position = targert.transform.localPosition + new Vector3 (0,0.5f,2);
        transform.position = targert.transform.TransformPoint (new Vector3 (0,0.5f,1));
        particleEffects = GetComponentsInChildren<ParticleSystem> ();
        for (int i = 0; i < particleEffects.Length; i++)
        {
            if (particleEffects [i].duration > effectTime)
                effectTime = particleEffects [i].duration; //找到粒子数组中播放时间最长的一个特效

            particleEffects [i].Play ();
            particleEffects [i].loop = false;
        }

    }

    void Update()
    {
        effectTime -= Time.deltaTime;
        if (effectTime <=0) 
        {
            for (int i = 0; i < particleEffects.Length; i++)
            {
                particleEffects [i].Stop();
            }
            this.gameObject.SetActive (false);

        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值