這只是我覺得目前比較重要且在項目中遇到的知識點
想要更詳細了解可以去看看Randy的博客:https://zhuanlan.zhihu.com/p/105029905
還可以去b站搜傅老師學黑魂復刻,也是會學到不少3D動畫系統的東西
所遇問題及解決
- 問題:單個方向沒有問題,斜着走時速度會達到1.414,也就是根號2
在B站學習傅老師的黑魂復刻教學學到的
float input = Mathf.Sqrt(Dright * Dright + Dup * Dup);
Dmag = input>1.0f?1.0f:input;//控制輸入大小
缺點:在未到1.0f前曲線平滑,但在1.0f~1.414突然強制轉換為1.0f,導致原本的增速整體變快
橢圓映射法

public Vector2 SquareToCircle(Vector2 input)
{
Vector2 output = Vector2.zero;
output.x = input.x * Mathf.Sqrt(1 - (input.y * input.y) / 2.0f);
output.y = input.y * Mathf.Sqrt(1 - (input.x * input.x) / 2.0f);
return output;
}
- 問題:trigger觸發變量快速連續按兩下時會累計,然后連續播放兩次
在切換動畫機的狀態添加腳本,使用On Enter和On Exit函數重置trigger
知識點
Animator窗口

Avatar:動畫節點導引替身,與動畫復用(尤其是人形動畫復用)有關,通過配置和應用Avatar,可以實現不同FBX模型之間的動畫復用
Apply Root Motion:是否將動畫中的根節點位移,植入到Unity中的物體位移上
簡單來說就是:是否要讓動畫師來決定角色的位移
RootMotion模式
-
勾選上時:導入的動畫自帶位移(動畫師先前做動畫時設置好的),優點:不會出現滑步現象(即是位移速度和動畫不匹配)
-
不勾選上時:不帶位移,若無腳本控制則是原地做動作,比如原地走路,優點:可以進行模型的位置修正
-
用OnAnimatorMove來使用腳本控制何時Apply,何時不用,當動畫需要某些條件或者修正時
Update Mode:狀態機播放動畫的時間模式
Normal:使用游戲Upadte的更新模式,一般常用於普通角色動畫
Animate Physics:使用物理周期的更新模式,用於角色與物體有物理交互或有物理位移時
Unscaled Time:不受TimeScal影響的更新模式,常用於GUI界面的動畫
Culling Mode:剔除模式
Always Animate:無論物體是否被攝像機可見,總是計算所有節點的運動,完整的進行動畫播放,常用於主角
Cull Update Transforms:當物體不被攝像機可見時,僅計算根節點的位移植入,保證物體位置上的正確,常用於配角以優化游戲,如GTA的路人
Cull Completely:當物體不被攝像機可見時,完全終止動畫的運行,用於消耗性能較高的動畫
狀態面板
圖為動畫控制器里狀態機的一個狀態面板

Motion:這個State所引用的動畫片段,Unity中的動畫片段,分為兩種
-
通過剪輯FBX中的整段動畫生成的動畫切片(Clip)
-
由Unity提供的Animation窗口創建出的動畫片段(Clip)
Speed:控制動畫的播放速度,1為正常速度,-1倒着放
可選中用Parameter控制:
-
Multiplier:Speed的一個倍率因子,可用float
-
Normalized Time:片段播放位置,取值0到1之間,可用float獲取播放進度
-
Mirror:是否進行左右翻轉,可用bool控制
-
Cycle Offset:偏移量,可用float
Foot IK:腳部的IK反向力學修正,如樓梯,上坡,爬梯
優先級
Transitions:從一個狀態出發的過渡,存在優先級的順序,越靠上方的過渡,優先級越大,我們可以通過拖動過渡來排列優先順序
動畫過渡面板

選中任意過渡線Gizmo,會出現如上動畫過渡面板
用於調試
-
Solo:勾選時,該State只能進行該過渡,其它過渡將無效
-
Mute:勾選時,這個過渡將無效,當測試某兩個動畫間的過渡時,可用這個將其中可能過渡到別的動畫的過渡線無效化
Settings:對過渡的加強版設置,可調整過渡細節
Interruption Source:打斷來源,允許該過渡被來自CurrentState或NextState的其它過渡打斷
動作游戲需注意此點掌握
Conditions:過渡條件,可添加多個動畫參數,則最終決定於其所有參數交集
中間時間條就是二者過渡時的融合比例,可手動拉拽選擇融合比例大小
Has Exit Time
勾選時上一個狀態對於的動畫片段必須被播放到末尾,才允許這個過渡被觸發,不勾選可以在任意時刻進行過渡
如果你發現動畫過渡有延遲或者是不流暢時,很大可能就是這個勾選了,但一般是有過度參數才將其選擇取消勾選,若無過渡的Parameters參數,則大部分情況是對該過渡速度要求不高,建議勾選上
動畫事件的插入
-
通過剪輯FBX中的整段動畫生成的動畫切片
可以在FBX面板的Events處添加關鍵幀事件,對着想插入的時間點右鍵即可,還可選擇參數和事件

-
Animation窗口創建出的動畫片段
可以在Animation窗口先用白線確定事件插入時間點,再點擊插入事件

-
StateMechineBehaviour提供的狀態事件腳本
選中任意狀態,用Add Behaviour添加即可

每個狀態事件腳本都有如下五個接口:
-
OnStateEnter:當進入該狀態的過渡被觸發時調用
-
OnStateUpdate:進入該狀態時循環調用
-
OnStateExit:如果曾進入過該狀態,之后進入到其它狀態時被調用
-
OnStateMove:相當於Mono腳本中OnAnimatorMove的作用,使用之前提到的RootMotion模式三,但僅針對這個State狀態運行時
-
OnStateIK:相當於Mono腳本中的OnAnimatorIK的作用,但僅針對這個State狀態運行時
Enter和Exit很適合用於動畫開始和結束的音效控制
-
-
通過普通腳本控制動畫的進行和過程中的事件觸發
腳本中獲取動畫參數的方法
Parameters動畫參數分為四種:float,int,bool,trigger
Trigger的觸發必須對當前狀態機的運行狀態進行判斷
int runHash=Animator.StringToHash("Run");//這里的名稱要與Animator窗口中,動畫參數的名稱對應
//通常對於調用頻繁的動畫參數我們使用哈希值進行快速訪問
//下面設置/獲取動畫參數均有使用String參數名稱進行映射的重載和使用哈希值進行映射的重載
//獲取設置Float類型參數,通常結合Input軸線
animator.GetFloat(floatHash);
animator.SetFloat(floatHash, Input.GetAxis("Horizontal"));
//獲取設置Int類型參數
animator.GetInteger(intHash);
animator.SetInteger(intHash,Number);
//獲取設置Bool類型參數
animator.GetBool(boolHash);
animator.SetBool(boolHash, true / false);
//觸發,取消觸發Trigger的方法
animator.SetTrigger(triggerHash);
animator.ResetTrigger(triggerHash);
AnimatorStateInfo 動畫器狀態信息
animator.GetCurrentAnimatorStateInfo(layerID);
用來獲取一個 AnimatorStateInfo 對象,有關當前或下一個狀態zd的動畫器信息版。
屬性
fullPathHash 該狀態的完整路徑哈希值,層名+狀態名
length 該狀態的當前持續長度。
loop 該狀態是否循環。
normalizedTime 該狀態的歸一化時間。
shortNameHash 使用Animator.StringToHash生成的哈希值。傳遞的字符串不包含父層的名權字。
tagHash 該狀態的標簽

Animator.StringToHash("Base Layer.Walk");//獲得state的fullPathHash
Animator.StringToHash("Walk");//獲得state的shortNameHash
Animator.StringToHash("Walking");//獲得Parameters變量
如果state和Parameters變量用一個名稱"Walk",然后用Animator.StringToHash("Walk")將獲得一樣的哈希值
如果不用同一名稱,然后Animator.StringToHash將獲得不同的哈希值
