Unity之Animation
- 一、Avatar
- 1.創建Avatar
- (1)Legacy
- (2)Generic
- (3)Humanoid
- 二、Animation視圖
- 1.影片時間軸
- (1)關鍵幀清單時間軸模式
- (2)曲線時間軸模式
- 2.創建新影片剪輯
- 3.支持的可影片屬性
- 4.曲線編輯
- 5.添加影片事件
- 三、Animator Controller
- 1.影片引數
- 2.狀態機
- 3.影片層
- 4.Mute 和Solo
- 5.目標匹配
- 6.反向動力學
- 四、混合樹
- 1.創建混合樹
- 2.混合型別
- (1)1D混合:
- (2)2D混合:
- (3)直接混合:
- 3.Animator Override Controller
- 五、性能和優化
- 1.影片系統
- (1) 控制器
- (2)簡單影片
- (3)縮放曲線
- (4)層
- (5)人形影片型別與通用影片型別
- (6)場景級別優化
- 2.運行時的優化
一、Avatar
Unity使用Avatar系統來識別布局中的特定影片模型是否為人形,以及模型的哪部分對應于腿、手臂、頭和軀干,Avatar可將影片從一個人形角色映射到另一個角色,允許重定位和反向動力學(IK),
1.創建Avatar
在匯入一個角色影片模型之后,可以在 Import Settings 面板中的 Rig 選項下指定角色影片模型的影片型別,包括 Legacy、Generic 以及 Humanoid 3 種模式,如下圖所示,

(1)Legacy
舊版影片型別,Unity4.0版本以前推出的影片系統,一般影片由Mecanim系統匯入,但無法使用人形影片的專有功能,
(2)Generic
一般影片型別,支持非人形(怪物)影片,也支持人形影片,但它無法使用Humanoid影片重定向功能,即模型只能使用自帶骨骼所制作的影片,不能給其他模型使用
(3)Humanoid
使用Humanoid(人形影片),如上圖所示,點擊Animation Type選項右側的下拉串列,選擇Humanoid,然后點擊Apply,Mecanim影片系統會自動將用戶所提供的骨架結構與系統內部自帶的簡易骨架進行匹配,如果匹配成功,Avatar Definition 下的 Configure 復選框會被選中,同時在 Assets 檔案夾中,一個 Avatar 子資源會被添加到模型資源中,
二、Animation視圖

1.影片時間軸
影片視圖面板右邊是當前編輯的時間軸,每個影片屬性的關鍵幀都顯示在此時間軸中,時間軸視圖有兩個模式:關鍵幀清單模式(Dopesheet)和時間線模式,點擊對應按鈕進行對用模式切換,
(1)關鍵幀清單時間軸模式
可通過框選方式選擇多個關鍵點,通過此功能可一次選擇和操作多個關鍵點,

(2)曲線時間軸模式
可通過框選方式選擇多個關鍵點,通過此功能可一次選擇和操作多個關鍵點,

(3)回放和幀導航
2.創建新影片剪輯
可如下圖所示建立:

可以在錄制的情況下拖動錄制影片的物件,也可在物件的屬性面板里修改屬性來錄制影片,也可在影片時間軸直接創建物件某個屬性,再在時間軸右側手動添加關鍵幀,輸入對應的影片數值,
3.支持的可影片屬性
Float、Color、Vector2、Vector3、Vector4、Quaternion、Boolean,
4.曲線編輯
將影片視圖切換到Curves,點擊關鍵幀可以對其進行拖動,修改其傾斜角度,也可點擊右鍵進行更復雜的屬性設定,
5.添加影片事件
如下圖所示添加影片事件:

三、Animator Controller
在 Animator 視窗中可創建、查看和修改 Animator Controller 資源,Animator 視窗有兩個主要部分:主要網格化布局區域以及左側 Layers 和 Parameters 面板,帶有深灰色網格的主要部分是布局區域,使用此區域可在Animator Controller中創建、排列和連接狀態,左側面板可在 Parameters 視圖和 Layers 視圖之間切換,Parameters 視圖 允許您創建、查看和編輯 Animator Controller 引數,這些引數是您定義的變數,充當狀態機的輸入,要添加引數,請單擊加號圖示,然后從彈出選單中選擇引數型別,要洗掉引數,請在串列中選擇引數,然后按 Delete 鍵(在 macOS 上使用 fn-Delete 來洗掉所選引數),

1.影片引數
可以通過影片曲線更新引數的值,然后通過腳本訪問引數來控制一些特定的屬性值,腳本同樣可設定被Mecanim拾取的引數值,例如,腳本可以設定引數來控制混合樹,可在Animator視窗的Parameters界面來設定默認引數值,引數值分為四個基本型別:
Integer - 整數
Float - 帶小數部分的數字
Bool - true 或 false 值(由復選框表示)
Trigger - 當被過渡使用時,由控制器重置的布林值引數(以圓形按鈕表示)

可使用Animator類中的函式,從腳本為引數賦值:
using UnityEngine;
using System.Collections;
public class SimplePlayer : MonoBehaviour {
Animator animator;
// 使用此函式進行初始化
void Start () {
animator = GetComponent<Animator>();
}
// 每幀呼叫一次 Update
void Update () {
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
bool fire = Input.GetButtonDown("Fire1");
animator.SetFloat("Forward",v);
animator.SetFloat("Strafe",h);
animator.SetBool("Fire", fire);
}
void OnCollisionEnter(Collision col) {
if (col.gameObject.CompareTag("Enemy"))
{
animator.SetTrigger("Die");
}
}
}
2.狀態機
Create Sub-State Machine創建,角色通常具有包含若干階段的復雜動作,合理的做法是識別單獨階段并將單獨狀態用于每個階段,而不是用單個狀態來處理整個動作,允許您將一組狀態折疊為狀態機圖中的單個指定項,這些折疊的狀態組稱為子狀態機,若要創建子狀態機,可右鍵單擊 Animator Controller 視窗中的空白空間,并從背景關系選單中選擇 Create Sub-State Machine,子狀態機在編輯器中用細長六邊形表示以區別于正常狀態,

3.影片層
單擊視窗右側的齒輪可顯示該層的設定,

在每一層上,您可以指定遮罩(應用影片的影片模型的一部分)以及混合型別,Override 表示將忽略其他層的資訊,而 Additive 表示將在先前層之上添加影片,
可以通過按小部件上方的 + 來添加新層,
Mask 屬性用于指定此層上使用的遮罩,例如,如果您只想播放模型上半身的投擲影片,同時讓角色也能夠行走、奔跑或站立不動,則可以在層上使用一個遮罩,從而在定義上半身部分的位置播放投擲影片:

Layers 側邊欄中顯示“M”符號,表示該層已應用遮罩,
影片層同步可以實作不同層中復用同一狀態機,例如,如果想要模擬“受傷”行為,并生成“受傷”狀態下的行走/奔跑/跳躍影片,而不是“健康”狀態下的影片,您可以單擊其中一個層上的 Sync 復選框,然后選擇要同步的層,隨后狀態機的結構便會相同,但狀態使用的實際影片剪輯不同,
這意味著同步的層根本沒有自己的狀態機定義,而是同步層狀態機的一個實體,在同步層視圖中對狀態機的布局或結構所做的任何更改(例如,添加/洗掉狀態或過渡)都是針對同步層的源進行的,同步層的唯一獨特更改是每個狀態內使用的選定影片,
通過 Timing 復選框,Animator 可調整同步層中每個影片所需的時間(由權重決定),如果取消選中 Timing,則會調整同步層上的影片,該調整會將影片的長度拉伸到與原始層上的一致,如果選中該選項,則影片長度將在兩個影片之間平衡(基于權重),在兩種情況下(選中和不選中),Animator 都將調整影片的長度,如果不選中,則原始層將是唯一母版,如果選中,則采用折中方案,

4.Mute 和Solo
Mute會禁用過度
Solo僅播放該過度

可設定多個 Solo 過渡以僅播放啟用了 Solo 的過渡,如果一個過渡啟用了 Solo,則 Unity 將對其他過渡啟用 Mute,如果同時啟用 Solo和 Mute,則 Mute將優先執行,
控制器圖并非始終反映引擎的內部 Mute 狀態,
5.目標匹配
通常在游戲中可能出現以下情況:角色必須以某種方式移動,使得手或腳在某個時間落在某個地方,例如,角色可能需要跳過踏腳石或跳躍并抓住頂梁,想象一下,您想安排一個角色跳到一個平臺的情況,并對這種情況已經有名為 Jump Up 的影片剪輯,首先,您需要在影片剪輯中找到角色開始離地的位置,注意在本示例中,此位置是影片剪輯中標準化時間的 14.1% 或 0.141,您還需要在影片剪輯中找到角色即將落地的位置,在本示例中,此位置為 78.0% 或 0.78,
using UnityEngine;
using System;
[RequireComponent(typeof(Animator))]
public class TargetCtrl : MonoBehaviour {
protected Animator animator;
//場景中的平臺物件
public Transform jumpTarget = null;
void Start () {
animator = GetComponent<Animator>();
}
void Update () {
if(animator) {
if(Input.GetButton("Fire1"))
animator.MatchTarget(jumpTarget.position, jumpTarget.rotation,
AvatarTarget.LeftFoot, new MatchTargetWeightMask(Vector3.one, 1f),
0.141f, 0.78f);
}
}
}
6.反向動力學
大多數影片是通過將骨架中的關節角度旋轉到預定值來生成的,子關節的位置根據父關節的旋轉而改變,因此可從父關節包含的各個關節的角度和相對位置來確定關節鏈的終點,這種構建骨架的方法被稱為正向動力學,
然而,從相反視角看待構建關節的任務通常很有用:在空間中選擇一個位置后,向后找到一種有效的關節定位方法,使終點落在該位置,如果您希望角色觸摸位于用戶選定位置的物件或讓角色的雙腳牢牢扎入不平坦的表面,這種方法可能很有用,此方法稱為反向動力學 (IK),可在 Mecanim 中用于_已正確配置的任何人形Avatar骨骼,

要為角色設定 IK,通常要在場景周圍放置與角色互動的物件,然后通過腳本(尤其是,諸如 SetIKPositionWeight、 SetIKRotationWeight、 SetIKPosition、 SetIKRotation、 SetLookAtPosition、 bodyPosition、 bodyRotation之類的 Animator 函式)來設定 IK
在上圖中,我們展示了一個抓住圓柱形物體的角色,我們如何將其實作?
我們從擁有有效的 Avatar角色開始,
下一步創建 Animator Controller,使其包含該角色的至少一個影片,然后,在 Animator 視窗的 Layers 面板中,單擊層的齒輪設定圖示,并選中彈出框中的 IK Pass 復選框,

設定默認層的 IK Pass 復選框,
確保已將 Animator Controller 分配給角色的 Animator 組件 (Animator Component):

接下來,為其附加一個實際處理 IK 的腳本,將此腳本命名為 IKControl,此腳本為角色的右手設定 IK 目標,并設定角色的觀察位置以使其觀看所持物體:
using UnityEngine;
using System;
using System.Collections;
[RequireComponent(typeof(Animator))]
public class IKControl : MonoBehaviour {
protected Animator animator;
public bool ikActive = false;
public Transform rightHandObj = null;
public Transform lookObj = null;
void Start ()
{
animator = GetComponent<Animator>();
}
// 用于計算 IK 的回呼
void OnAnimatorIK()
{
if(animator) {
// 如果 IK 處于活動狀態,請將位置和旋轉直接設定為目標,
if(ikActive) {
// 設定觀察目標位置(如果已分配)
if(lookObj != null) {
animator.SetLookAtWeight(1);
animator.SetLookAtPosition(lookObj.position);
}
// 設定右手目標位置和旋轉(如果已分配)
if(rightHandObj != null) {
animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1);
animator.SetIKPosition(AvatarIKGoal.RightHand,rightHandObj.position);
animator.SetIKRotation(AvatarIKGoal.RightHand,rightHandObj.rotation);
}
}
// 如果 IK 未處于活動狀態,請將手和頭部的位置和旋轉設定回原始位置
else {
animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0);
animator.SetLookAtWeight(0);
}
}
}
}
因為我們不打算讓角色的手伸到物體內部中心(圓柱的軸心點),所以放置一個空的子物件(在此情況下,命名為“Cylinder Grab Handle”(圓柱抓握把手)),確保手應該放在圓柱上,并將其相應旋轉,然后,這只手瞄準此子物件,

一個空的子游戲物件充當 IK 目標,因此這只手將正確放在可見的圓柱物件上
然后,應將此“抓握把手”游戲物件分配為 IKControl 腳本的“Right Hand Obj”屬性
在此示例中,我們把觀察目標設定為圓柱本身,因此即使把手靠近底部,角色也會直接看向物體的中心,

四、混合樹
1.創建混合樹
滑鼠游標放到網格空白區域右鍵Create State->From New Blend Tree:


使用影片剪輯和輸入引數來設定混合樹時,Inspector 視窗通過圖形顯示影片如何隨著引數值變化而進行組合(拖動滑動條時,樹根中的箭頭會改變其著色以顯示其控制的影片剪輯),

2.混合型別
(1)1D混合:
混合節點的 Inspector中的第一個選項是 Blend Type,此下拉選單用于選擇不同混合型別之一;這些型別可以根據一個或兩個引數進行混合,1D 混合根據單個引數來混合子運動,

(2)2D混合:
2D Simple Directional:最好在運動表示不同方向(例如“向前走”、“向后退”、“向左走”和“向右走”或者“向上瞄準”、“向下瞄準”、“向左瞄準”和“向右瞄準”)時使用,根據需要可以包括位置 (0, 0) 處的單個運動,例如“空閑”或“瞄準”,在 Simple Directional 型別中,在同一方向上_不_應該有多個運動,例如“向前走”和“向前跑”,
2D Freeform Directional:運動表示不同方向時,也使用此混合型別,但是您可以在同一方向上有多個運動,例如“向前走”和“向前跑”,在 Freeform Directional 型別中,運動集應始終包括位置 (0, 0) 處的單個運動,例如“空閑”,
2D Freeform Cartesian:最好在運動不表示不同方向時使用,憑借 Freeform Cartesian,X 引數和 Y 引數可以表示不同概念,例如角速度和線速度,一個示例是諸如“向前走不轉彎”、“向前跑不轉彎”、“向前走右轉”、“向前跑右轉”之類的運動,

(3)直接混合:
使用直接混合樹可將 Animator 引數映射到 BlendTree 子項的權重,如果您想要精確控制所混合的各種影片而不是使用一個或兩個引數來間接混合它們(1D 和 2D 混合樹便是這種情況),這將非常有用,

3.Animator Override Controller
Animator Override Controller 是一種資源,它可讓您擴展現有 Animator Controller,從而替換使用的特定影片但保留其原始結構、引數和邏輯,
因此,您可以創建同一個基本狀態機的多個變體,但是每個變體使用不同的影片集,例如,您的游戲可能有各種各樣的 NPC 類角色生活在世界上,但每種型別(小妖精、惡魔、小精靈等)都有自己獨特的行走、空閑、坐定等影片,
通過創建一個包含所有 NPC 型別角色邏輯的“基礎”Animator Controller,即可為每種角色型別創建一個重寫,并放入各自的影片檔案,

五、性能和優化
1.影片系統
(1) 控制器
未設定控制器的 Animator 不會花時間執行處理,
(2)簡單影片
播放沒有混合的單個影片剪輯會使 Unity 的速度比舊版影片系統更慢,舊系統非常直接,對曲線采樣并直接寫入變換中,Unity 的當前影片系統具有用于混合的臨時緩沖區,并會對采樣曲線和其他資料進行額外復制,當前系統布局已針對影片混合和更復雜設定進行優化,
(3)縮放曲線
影片化縮放曲線比影片化移動和旋轉曲線的成本更高,為了改善性能,請避免使用縮放影片,
注意:這不適用于常量曲線(具有相同影片剪輯長度值的曲線),常量曲線經過優化,成本低于比普通曲線,常量曲線的值與默認場景值相同時,常量曲線不會每幀都寫入場景,
(4)層
大多數時間,Unity 都在估算影片,并將影片層和影片狀態機的開銷保持在最低水平,向 Animator 添加另一層(無論同步與否)的成本取決于層播放的影片和混合樹,層的權重為零時,Unity 會跳過層更新,
(5)人形影片型別與通用影片型別
以下提示可幫助您選擇具體型別:
匯入人形影片時,如果不需要 IK(反向動力學)目標或手指影片,請使用 Avatar 遮罩 (class-AvatarMask) 將它們移除,
使用通用型別時,使用根運動比不使用根運動的成本更高,如果影片沒有使用根運動,請確保未指定根骨骼,
(6)場景級別優化
可進行許多優化,一些有用的提示如下:
使用哈希而不是字串來查詢 Animator,
實作一個小的 AI 層來控制 Animator,您可以讓它為 OnStateChange、OnTransitionBegin 和其他事件提供簡單回呼,
使用狀態標記可輕松地將 AI 狀態機與 Unity 狀態機匹配,
使用其他曲線來模擬事件,
使用其他曲線來標記影片;例如,與目標匹配一起使用,
2.運行時的優化
始終通過將 Animator 的 Culling Mode 設定為 Based on Renderers 來優化影片,并禁用蒙皮網格渲染器的 Update When Offscreen 屬性,這樣即可在角色不可見時讓 Unity 不必更新影片,
參考文獻:
Unity官方手冊
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/339275.html
標籤:其他
上一篇:網路協議-基礎知識(筆記)
下一篇:100個人圍成圈, 從第一個人開始從1開始報數,逢14的倍數的, 將當前人踢出游戲,最后問最后一個被踢出去的是剛開始100人的第幾個人?
