動畫腳本 Animation Scripting
Unity's 動畫系統允許你創建一個漂亮的動畫蒙皮角色. 動畫系統支持動畫融合,混合,添加動畫,步調週期時間同步.動畫層.控制動畫回放的所有方面(時間,速度,混合權重) 每個頂點有1.2.4個骨骼影響的mesh,基於物理系統的布娃娃系統,另外還有程序動畫.爲了獲得最佳效果推薦您在製作模型和動畫綁定前閱讀一下 Modeling Optimized Characters 章節.
製作一個動畫角色主要包括兩個方面; 在世界中移動 和 由此產生的動畫. 如果你想了解角色移動相關的更多內容, 請參閱Character
Controller page.
你可以下載 example demos 中預設置好的動畫角色. 當你學完本頁的基礎部分你還可以看一看 animation script interface.
·
·
·
·
·
·
Animation Blending 動畫融合
在現今的遊戲中Animation Blending是一項保證遊戲動畫順暢過渡的基本的特性.動畫師創建的動畫例如: walk循環, run 循環, idle原地空閒動畫 或射擊動畫.在遊戲的任何時間點你都有可能從空閒站立轉換到走動,反之亦然. 當然你不希望兩個不同的動作之間突然跳轉, 你需要動畫平滑過渡.
而這個問題的解決就依賴動畫融合技術. 在Unity中你可以讓同一個角色擁有任意數量的動畫.所有這些動畫融合添加成爲一個總的動畫.
首先我們來爲一個角色添加兩個動畫原地空閒站立和走動並平滑的使這兩個動畫過渡. 爲了使我們在寫腳本時簡單些, 首先我們設置動畫的 Wrap Mode爲 Loop. 然後關閉 Play Automatically來讓我們的腳本來獨佔動畫的播放.
我們第一個動畫腳本很簡單; 我們需要一些方法來探查角色移動的有多快, 然後在走和站立之間淡入淡出. 在這個簡單的測試中我們使用 pre-setup input axes.
function Update () {
}
下面我們來讓這個腳本運行:
1.
2.
3.
點擊Play 按鈕, 當你按上下鍵時角色會走動,鬆開上下鍵時角色站立不動.
層是一個非常有用的概念它可以讓你將動畫片段任意成組並且區分優先順序.
在Unity's動畫系統中, 你可以混合任意數量的動畫片段. 你可以手工分配權重或者直接使用animation.CrossFade(),來自動分配權重.
混合權重混合權重總是在應用前被規格化 normalized
比如說我們現在有一個 walk
cycle 和一個run
cycle, 權重都是1
(100%).當unity計算最終動畫時會規格化權重, 這意味着 walk佔50% 權重,
這在大多數情況下都是不錯的, 但當兩個動畫片段同時運行而其中一個權重明顯大於另外一個. 那麼你需要手動調整權重值,但如果你使用動畫層來解決這個問題過程會容易得多.
例如現在你有一個射擊動畫, 一個空閒站立,一個走動循環
爲了達到這一目的最簡單的方法是在射擊時簡單的保持 walk 和 idle動畫. 接下來需要確定shoot
animation在一個比idle 和walk更高的層. 這意味着shoot
animation 將首先收到混合權重.
function Start () {
}
function Update () {
}
默認情況下 animation.Play() 和 animation.CrossFade() 將停止或淡出在同一層裏面的動畫. 這是我們在絕大多數情況下需要的. 在我們shoot, idle, run 範例中, 播放 idle 和 run 將不會影響到 shoot動畫 反之亦然 (you can change this behavior(行爲) with an optional parameter(任意參數) to animation.CrossFade if you like).
動畫混合可以讓你縮減你必須爲遊戲製作的動畫片斷數量 ,方法是製作只對身體某個部分起作用的動畫. 這意味着這些動畫可以和其他動畫合併起來一起使用.
如果你想給一個動畫添加 animation mixing transform to an animation by calling AddMixingTransform() on the given AnimationState.
例如你可能有一個揮手(hand-waving)動畫. 你可能需要讓一個空閒站立(idle)角色或者一個走動(walking)角色 來揮手. 如果沒有動畫混合你可能需要製作兩個揮手hand-waving動畫 : 一個給 idle, 一個給walking. 可是, 如果你將揮手(hand-waving)動畫作爲一個mixing transform 添加到shoulder transform,揮手動畫將只控制肩膀. 身體餘下部位不受其影響, 下半身會繼續播放 idle 或者walk 動畫. 因而你只需要一個揮手(hand-waving)動畫.
/// Adds a mixing transform using a Transform variable
var shoulder : Transform;
animation["wave_hand"].AddMixingTransform(shoulder);
Another example using a path.
function Start () {
}
附加動畫和動畫混合可以讓你縮減爲遊戲製作的動畫片斷的數量,並且對面部動畫(facial animations)來說非常重要.
讓我們來看看如果創建一個在跑和轉身時身體可以自動傾斜的角色.
你已經製作好了一個 walk 和 run循環, 現在你還要製作一個走動左傾( walk-lean-left), 走動右傾(walk-lean-right), 跑左傾(run-lean-left), 跑右傾(run-lean-right)動畫.
這意味着你需要多做4個動畫片斷! 製作這麼多數量的動畫會累死人的. 而附加動畫(Additive animations) 和混合(Mixing) 可以大大減少這些工作量!
附加動畫範例 Additive Animation Example
附加動畫允許你在頂層覆蓋其他所有可能播放的動畫的效果( allow you to overlay the effects of animation on top of any others that may be playing). 當你製作一個附加動畫時, Unity將計算動畫片斷裏的第一幀 (first frame)和當前幀(current frame)的差異. 然後它將在所有其他播放的動畫之上應用這個差異(Then it will apply this difference on top of all other playing animations).
現在你只需要製作一個左傾( lean-left) 和右傾( lean-right)動畫. Unity將爲此傾斜動畫新建一個層並置於walk, idle 或 run循環的層級之上.
下面是代碼Here is the code to make that happen:
private var leanLeft : AnimationState;
private var leanRight : AnimationState;
function Start () {
}
// Every frame just set the normalized time
// based on how much lean we want to apply
function Update () {
}
提示Tip:
當使用附加動畫時它會判斷你同時也在播放一些其他的使用了附加動畫的非附加動畫(it is critical that you are also playing some other non-additive animation on every transform that is also used in the additive animation), 否則動畫將添加到最後一幀結果的頂部(animations will add on top of the last frame's result). 這通常不是你所需要的 (This is most certainly not what you want).
程序動畫角色Procedurally Animating Characters
有時你需要程序化的驅動你的角色骨骼. 例如你可能需要你的角色的頭注視3d空間的某個點. 這個活最好讓腳本來幹. 幸運的是, Unity做這個很容易. 在Unity 中所有骨骼來驅動蒙皮網格(skinned mesh)的變換(Transforms). 因而你可以給角色的骨骼寫腳本,就和其他GameObject一樣.
很重要的一點是動畫系統updates
the Transforms 是在Update() function調用之後
布娃娃系統Ragdolls 也是用同樣的方法製作出來的. 你可以簡單的把剛性物體(Rigidbodies), 角色關節(Character Joints) 和 膠囊碰撞體(Capsule Colliders)連接給不同的骨骼. 這樣物理系統就可以作用於蒙皮角色(skinned character). (什麼是布娃娃系統,當你在射擊類遊戲中打死對手時可以注意到當角色快接近地面時,他的四肢開始癱軟在地面上,這個不是動畫師調出來的,而是布娃娃系統自動計算出來的。)
動畫重放和取樣Animation Playback 和 Sampling
這一部分 將說明引擎如何在動畫重放時取樣.
動畫片斷製作時總是有一個特定的速率. 舉例來說, 你可能在Max 或Maya at 創建了一個幀速爲 60 frames 每秒(fps)的動畫. 當導入 Unity後, 輸入模塊將讀取幀速, 所以導入的動畫幀速還是60fps.
可是, 遊戲運行時的速率是不斷變化的. 有的電腦幀速快有的電腦幀速慢, 即使是同一臺電腦前一秒和後一秒因爲視角的不同幀速也不一樣. 基本上當遊戲開始運行時我們無法確定一個精確的幀速. 這意味着即使我們的動畫片斷製作時是 60 fps, 它重放時也許用的是另外一個速率, 例如 56.72 fps, 或 83.14 fps. 它可以變成任何一個速率.
Unity 對這些變化的速率取樣, 不在於其製作時的速率. 幸運的是,3d電腦圖形動畫不是由分散的動畫組成, 確切地說是由連續的曲線構成的. 這些曲線可以讓我們在任何時間點取樣; 而不是適配某一個原始幀的時間點. I這也意味着如果遊戲運行速率高於原始製作速率, 動作事實上看起來會更平滑流暢.
對絕大多數應用場合,
同樣需要注意的是變化的幀速採樣結果, 一個使用WrapMode.Once 模式重放的動畫的採樣不一定是精確的最後一幀( last frame).在遊戲中很有可能是剛好結束前的某一幀, 在下一幀時間可能超過動畫的長度, so it is disabled 和 not sampled further. 如果你需要動畫的最後一幀採樣精確,你可以使用WrapMode.ClampForever. 如果是那樣的話動畫將不停的對最後一幀進行採樣直到你自己停止動畫.