我覺得這是一個很難發現卻很重要的問題。
很多人試玩了我的遊戲後反應動作有延遲。
本來以為是動作或碰撞判定的問題,後來才發現是 Animator 對連續輸入的反應所致。
一般來說,玩家輸入幾次,Animator Trigger 就會觸發幾次。
舉例來說,如果玩家按三下攻擊,Animator 就會演出三次攻擊動畫。
這聽起來很合理。
但是假如攻擊動畫有一秒,玩家手速超快,在一秒之內按了十次,你就會看到在接下來的十秒角色都在攻擊。
然而玩家心理預期的是手一放開,角色就該停止動作。
那這要怎辦咧?
首先先做一張表
以這張表為例,移動之後可以接任何動作。
普攻之後只能接移動,其他的都不行。
然後把它寫成txt,或是任何程式可以讀的檔案。
然後是程式的部分
protected override void Update() { base.Update(); //將輸入的 keycode 塞進 queue 中 KeyCode keyCode = KeyCode.Escape; if (Input.GetKeyDown(KeyCode.X)) { keyCode = KeyCode.X; } if (Input.GetKeyDown(KeyCode.A)) { keyCode = KeyCode.A; } if (Input.GetKeyDown(KeyCode.C)) { keyCode = KeyCode.C; } if (Input.GetKeyDown(KeyCode.Z)) { keyCode = KeyCode.Z; } if (keyCode != KeyCode.Escape) { _actionQueue.Enqueue(keyCode); //如果 queue 中只有一個 keycode,就立刻執行動畫 if (_actionQueue.Count == 1) { _lastKeyCode = keyCode; SetAnimation(keyCode); } } } private void SetAnimation(KeyCode keyCode) { //X是普攻,會根據目前是否有輸入向上或向下來判斷是向上、向下、或向前的攻擊 if (keyCode == KeyCode.X) { if (Input.GetKey(KeyCode.UpArrow)) { AttackUp(); } else if (Input.GetKey(KeyCode.DownArrow)) { AttackDown(); } else { Attack(); } } //其他的動作指令 if (keyCode == KeyCode.A) { SkillA(); } if (keyCode == KeyCode.C) { Dash(); } if (keyCode == KeyCode.Z) { Jump(); } } void Attack() { Animator.SetTrigger("Attack"); } |
在這些動作的動畫的最後一幀加入 Event,執行 OnActionEnd
OnAnimationEnd 的程式
public void OnActionEnd() //動作結束的時候 { if (_actionQueue.Count > 0) { _actionQueue.Dequeue(); if (_actionQueue.Count > 0) { KeyCode currentKeyCode = _actionQueue.Peek(); ContinueActionData.ActionEnum currentActionEnum = KeyCodeToActionEnum(currentKeyCode); ContinueActionData.ActionEnum lastActionEnum = KeyCodeToActionEnum(_lastKeyCode); //判斷是否為可連續的動作 if (ContinueActionData.Data[(int)lastActionEnum, (int)currentActionEnum]) { _lastKeyCode = currentKeyCode; SetAnimation(currentKeyCode); } else { _actionQueue.Clear(); } } } } |
攻擊動作結束時 dequeue
根據上面那張表來判斷攻擊之後可不可以接衝刺,答案是不行。
所以衝刺的指令會被忽略。
反之,如果是可連續的動作就會執行該動作。
還有一個問題是 Animatio Exit Time
舉例來說,角色的普通攻擊有兩段動作。
第一下普通攻擊結束後一段時間內再次進行的普通攻擊會不一樣。
這段時間就是 Exit Time
以我的遊戲為例,X之後0.5內再次按X就會進行 SecondAttack
這個 0.5 的單位好像不是秒,而是動畫長度的 normalized time
大概就是這樣...
這個問題超坑爹的。我就是玩了幾十年的遊戲都沒發現這個問題。
卻會一直讓人覺得"手感怪怪的"
多虧了專精動作遊戲的小夥伴才終於發現了這個問題。
希望這篇文章可以讓其他人避免被坑。