上節課講了unity 游戲內實作3連擊影片的實作,因為在游戲中我們的連擊影片可能會有很多,為了避免使用較多的if else 我們這節課開始參考狀態機來更好的實作效果,那么接下來我們就開始狀態機的講解!!!
首先是寫一個我們管理影片的狀態機
/// <summary>
/// 狀態機
/// </summary>
public class ActionState
{
public PlayerController playerc;
/// <summary>
/// 開始進入狀態該做什么
/// </summary>
public virtual void Enter()
{
OnEnter();
}
/// <summary>
/// 進入狀態回呼
/// </summary>
protected void OnEnter()
{
playerc.currentState = this;
this.playerc.stateName = this.GetType().ToString();//狀態名稱賦值 在這里為了更好地讓我們看到當前所在狀態,所以在public屬性面板可以看到
}
/// <summary>
/// 處理玩家輸入事件
/// </summary>
public virtual void HandleInput()
{
}
}
然后寫我們的玩家控制腳本 我們要把這個腳本掛在人物上
///玩家控制腳本
public class PlayerController : MonoBehaviour
{
public ActionState currentState;//當前的狀態
public Attack1 attack1;
public Attack2 attack2;
public Attack3 attack3;
public Attack4 attack4;
public IdleState idleState;
public Animator animator;
public bool leftMouse_KeyDown;//滑鼠左鍵
public bool leftControl_KeyDown;//左Ctrl鍵
public string stateName;//狀態名稱
private AnimatorStateInfo info;//顯示當前狀態名
/// <summary>
/// 判斷可不可以攻擊
/// </summary>
/// <param name="start">開始</param>
/// <param name="end">結束</param>
/// <returns></returns>
public bool CanAttack(float start, float end)
{
return info.normalizedTime >= start && info.normalizedTime <= end;
}
void Start()
{
animator=GetComponent<Animator>();
idleState = new IdleState() { playerc = this };
attack1 = new Attack1() { playerc = this };
attack2 = new Attack2() { playerc = this };
attack3 = new Attack3() { playerc = this };
attack4 = new Attack4() { playerc = this };
currentState = idleState;//默認設定當前狀態為休閑狀態
currentState.Enter();//進入休閑狀態
}
// Update is called once per frame
void Update()
{
leftMouse_KeyDown = Input.GetMouseButtonDown(0);//獲取滑鼠左鍵
leftControl_KeyDown = Input.GetKeyDown(KeyCode.LeftControl);//獲取左ctrl鍵
bool input_attack= leftMouse_KeyDown|| leftControl_KeyDown;//獲取當前輸入
info = this.animator.GetCurrentAnimatorStateInfo(0);//獲取當前狀態
if (currentState != idleState && !animator.IsInTransition(0) && info.IsName("Idle_A"))
{
idleState.Enter();
}
if (input_attack)//判斷當前輸入
{
currentState.HandleInput();//進入
}
}
}
接下來我們來寫我們的狀態類腳本 我們的Idle狀態和攻擊狀態都要繼承剛才所寫的ActionState去重寫我們的方法來實作狀態的切換
//狀態Idle
public class IdleState : ActionState
{
public override void HandleInput()
{
base.HandleInput();
if (playerc.leftMouse_KeyDown)//滑鼠左鍵
{
playerc.attack1.Enter();//攻擊1狀態進入
}
else if (playerc.leftControl_KeyDown)//左Ctrl鍵
{
playerc.attack2.Enter();//攻擊二狀態進入
}
}
public override void Enter()
{
base.Enter();
playerc.animator.CrossFade("Idle_A", 0.1f);//播放idle狀態
}
}
public class Attack4 : ActionState
{
public override void Enter()
{
base.Enter();
playerc.animator.CrossFade("Atk4", 0.1f);
}
public override void HandleInput()
{
base.HandleInput();
if (playerc.CanAttack(0.45f, 0.9f))
{
if (playerc.leftMouse_KeyDown)
{
playerc.idleState.Enter();
}
else if (playerc.leftControl_KeyDown)
{
playerc.idleState.Enter();
}
}
}
}
public class Attack3 : ActionState
{
public override void Enter()
{
base.Enter();
playerc.animator.CrossFade("Atk3", 0.1f);
}
public override void HandleInput()
{
base.HandleInput();
if (playerc.CanAttack(0.45f, 0.9f))
{
if (playerc.leftMouse_KeyDown)
{
playerc.attack4.Enter();
}
else if (playerc.leftControl_KeyDown)
{
playerc.attack1.Enter();
}
}
}
}
public class Attack2 : ActionState
{
public override void Enter()
{
base.Enter();
playerc.animator.CrossFade("Atk2", 0.1f);
}
public override void HandleInput()
{
base.HandleInput();
if (playerc.CanAttack(0.45f, 0.9f))
{
if (playerc.leftMouse_KeyDown)
{
playerc.attack3.Enter();
}
else if (playerc.leftControl_KeyDown)
{
playerc.attack4.Enter();
}
}
}
}
public class Attack1 : ActionState
{
public override void Enter()
{
base.Enter();
playerc.animator.CrossFade("Atk1", 0.1f);//播放對應影片
}
public override void HandleInput()
{
base.HandleInput();
if (playerc.CanAttack(0.45f,0.9f))
{
if (playerc.leftMouse_KeyDown)
{
playerc.attack2.Enter();
}
else if (playerc.leftControl_KeyDown)
{
playerc.attack3.Enter();
}
}
}
}
在這里就不多敲注釋了 只要實作了一個狀態 我們到后邊改變狀態就是復制粘貼的問題了

最后實作效果:
一直點擊滑鼠左鍵 :攻擊1-攻擊2-攻擊3-攻擊4-休閑
一直左Ctrl:攻擊2-攻擊4-休閑
先左鍵然后Ctrl接著左鍵再ctrl:攻擊1-攻擊3-攻擊2-攻擊4-休閑
在這里實作效果有很多就不一一列舉了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395683.html
標籤:其他
