1. 程式人生 > >Unity3D教程:動畫融合、動畫層、動畫混合、附加動畫、程式動畫、動畫重放和取樣

Unity3D教程:動畫融合、動畫層、動畫混合、附加動畫、程式動畫、動畫重放和取樣

原帖地址:http://www.unitymanual.com/5323.html

動畫指令碼 Animation Scripting

Unity's 動畫系統允許你建立一個漂亮的動畫蒙皮角色,動畫系統支援動畫融合,混合,新增動畫,步調週期時間同步.動畫層,控制動畫回放的所有方面(時間,速度,混合權重) 每個頂點有1.2.4個骨骼影響的mesh,基於物理系統的布娃娃系統,另外還有程式動畫.為了獲得最佳效果推薦您在製作模型和動畫繫結前閱讀一下 Modeling Optimized Characters 章節。。Unity3D教程手冊

製作一個動畫角色主要包括兩個方面; 在世界中移動 和 由此產生的動畫。如果你想了解角色移動相關的更多內容, 請參閱 Character Controller page.   實際上角色動畫是由Unity's 指令碼介面完成的。

你可以下載 example demos 中預設定好的動畫角色. 當你學完本頁的基礎部分你還可以看一看 animation script interface.

Animation Blending 動畫融合

在現今的遊戲中Animation Blending是一項保證遊戲動畫順暢過渡的基本的特性.動畫師建立的動畫例如: walk 迴圈, run 迴圈, idle原地空閒動畫 或射擊動畫.在遊戲的任何時間點你都有可能從空閒站立轉換到走動,反之亦然. 當然你不希望兩個不同的動作之間突然跳轉, 你需要動畫平滑過渡.

而這個問題的解決就依賴動畫融合技術. 在Unity中你可以讓同一個角色擁有任意數量的動畫.所有這些動畫融合新增成為一個總的動畫.

首先我們來為一個角色新增兩個動畫原地空閒站立和走動並平滑的使這兩個動畫過渡. 為了使我們在寫指令碼時簡單些, 首先我們設定動畫的 Wrap Mode為 Loop. 然後關閉 Play Automatically來讓我們的指令碼來獨佔動畫的播放.

我們第一個動畫指令碼很簡單; 我們需要一些方法來探查角色移動的有多快, 然後在走和站立之間淡入淡出. 在這個簡單的測試中我們使用 pre-setup input axes.

01
function Update () {
02
03
  if (Input.GetAxis(“Vertical”) > 0.2)
04
05
  animation.CrossFade
(“walk”);
06
07
  else
08
09
  animation.CrossFade (“idle”);
10
11
  }

下面我們來讓這個指令碼執行:

1.建立一個js指令碼 Assets->Create Other->Javascript.

2.把程式碼貼進去。

3.把指令碼拖拽給角色 character (It needs to be the same GameObject as the animation)

點選Play 按鈕, 當你按上下鍵時角色會走動,鬆開上下鍵時角色站立不動、

動畫層Animation Layers

層是一個非常有用的概念它可以讓你將動畫片段任意成組並且區分優先順序。在Unity's動畫系統中, 你可以混合任意數量的動畫片段。你可以手工分配權重或者直接使用animation.CrossFade(),來自動分配權重。。Unity3D教程手冊

混合權重混合權重總是在應用前被規格化 normalized。

比如說我們現在有一個 walk cycle 和一個run cycle,權重都是1 (100%).當unity計算最終動畫時會規格化權重,這意味著 walk佔50% 權重,   run cycle佔50% 權重。

這在大多數情況下都是不錯的, 但當兩個動畫片段同時執行而其中一個權重明顯大於另外一個 。那麼你需要手動調整權重值,但如果你使用動畫層來解決這個問題過程會容易得多。

製作動畫層的範例Layering Example

例如現在你有一個射擊動畫, 一個空閒站立,一個走動迴圈。 你需要在走和站兩個動作間持續的淡入淡出(在玩家走動速度的基礎上) 但當玩家射擊時我們只想展示射擊動畫。因而射擊動畫此時的優先度最高。

為了達到這一目的最簡單的方法是在射擊時簡單的保持 walk 和 idle動畫。接下來需要確定shoot animation在一個比idle 和 walk更高的層. 這意味著shoot animation 將首先收到混合權重.   walk 和idle 只有在 shoot animation不使用 100% 混合權重的情況下接收權重. 所以當 CrossFading the shoot animation in, 權重將從0開始很短時間內到達 100%. 在開始階段 walk 和 idle 層將依然可以收到混合權重 但當 shoot animation 完全切入時, 他們就收不到權重了。  這才是我們需要的!

01
function Start () {
02
03
  // Set all animations to loop 設定所有動畫為迴圈
04
05
  animation.wrapMode = WrapMode.Loop;
06
07
  // except shooting 除了射擊(不迴圈)
08
09
  animation[“shoot”].wrapMode = WrapMode.Once;
10
11
  //放置idle 和 walk 進低一級別的 layers  (預設 layer 總是 0)
12
13
  // This will do two things這將作兩件事情
14
15
  // - 當 calling CrossFade時,由於shoot 和 idle/walk 在不同的layers 中
16
17
  //   它們將不會影響互相之間的重放.
18
19
  // - 由於 shoot 在高一級的 layer, 當faded in 時shoot動畫將替換
20
21
  //   idle/walk 動畫 .
22
23
  animation[“shoot”].layer = 1;
24
25
  // Stop animations that are already playing停止已經播放的動畫
26
27
  //(萬一 user 忘記的話,自動disable播放)
28
29
  animation.Stop();
30
31
  }
32
33
  function Update () {
34
35
  // Based on the key that is pressed,基於按下的鍵
36
37
  // play the walk animation or the idle animation播放走,站動畫
38
39
  if (Mathf.Abs(Input.GetAxis(“Vertical”)) > 0.1)
40
41
  animation.CrossFade(“walk”);
42
43
  else
44
45
  animation.CrossFade(“idle”);
46
47
  // Shoot射擊
48
49
  if (Input.GetButtonDown (“Fire1”))
50
51
  animation.CrossFade(“shoot”);
52
53
  }

預設情況下 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

動畫混合可以讓你縮減你必須為遊戲製作的動畫片斷數量 ,方法是製作只對身體某個部分起作用的動畫。這意味著這些動畫可以和其他動畫合併起來一起使用。

如果你想給一個動畫新增 animation mixing transform to an animation by calling AddMixingTransform() on the given AnimationState.

混合範例Mixing Example

例如你可能有一個揮手(hand-waving)動畫. 你可能需要讓一個空閒站立(idle)角色或者一個走動(walking)角色 來揮手. 如果沒有動畫混合你可能需要製作兩個揮手hand-waving動畫 : 一個給 idle, 一個給walking. 可是, 如果你將揮手(hand-waving)動畫作為一個mixing transform 新增到shoulder transform,揮手動畫將只控制肩膀. 身體餘下部位不受其影響, 下半身會繼續播放 idle 或者 walk 動畫. 因而你只需要一個揮手(hand-waving)動畫。

01
/// Adds a mixing transform using a Transform variable
02
03
  var shoulder : Transform;
04
05
  animation[“wave_hand”].AddMixingTransform(shoulder);
06
07
  Another example using a path.
08
09
  function Start () {
10
11
  // Adds a mixing transform using a path instead
12
13
  var mixTransform : Transform = transform.Find(“root/upper_body/left_shoulder”);
14
15
  animation[“wave_h和”].AddMixingTransform(mixTransform);
16
17
  }

附加動畫 Additive Animations

附加動畫和動畫混合可以讓你縮減為遊戲製作的動畫片斷的數量,並且對面部動畫(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迴圈的層級之上.

下面是程式碼:

01
private var leanLeft : AnimationState;
02
03
  private var leanRight : AnimationState;
04
05
  function Start () {
06
07
  leanLeft = animation[“leanLeft”];
08
09
  leanRight = animation[“leanRight”];
10
11
  // Put the leaning animation in a separate layer
12
13
  // So that other calls to CrossFade won't affect it.
14
15
  leanLeft.layer = 10;
16
17
  leanRight.layer = 10;
18
19
  // Set the lean animation to be additive 混合模式為附加
20
21
  leanLeft.blendMode = AnimationBlendMode.Additive;
22
23
  leanRight.blendMode = AnimationBlendMode.Additive;
24
25
  // Set the lean animation ClampForever
26
27
  // With ClampForever animations will not stop
28
29
  // automatically when reaching the end of the clip
30
31
  leanLeft.wrapMode = WrapMode.ClampForever;
32
33
  leanRight.wrapMode = WrapMode.ClampForever;
34
35
  // Enable the animation 和 fade it in completely
36
37
  // We don't use animation.Play here because we manually adjust the time
38
39
  // in the Update function.
40
41
  // Instead we just enable the animation 和 set it to full weight
42
43
  leanRight.enabled = true;
44
45
  leanLeft.enabled = true;
46
47
  leanRight.weight = 1.0;
48
49
  leanLeft.weight = 1.0;
50
51
  // For testing just play “walk” animation 和 loop it
52
53
  animation[“walk”].wrapMode = WrapMode.Loop;
54
55
  animation.Play(“walk”);
56
57
  }
58
59
  // Every frame just set the normalized time
60
61
  // based on how much lean we want to apply
62
63
  function Update () {
64
65
  var lean = Input.GetAxis(“Horizontal”);
66
67
  // normalizedTime is 0 at the first frame 和 1 at the last frame in the clip
68
69
  leanLeft.normalizedTime = -lean;
70
71
  leanRight.normalizedTime = lean;
72
73
  }

提示Tip:

當使用附加動畫時它會判斷你同時也在播放一些其他的使用了附加動畫的非附加動畫, 否則動畫將新增到最後一幀結果的頂部,這通常不是你所需要的 。

 程式動畫角色Procedurally Animating Characters

有時你需要程式化的驅動你的角色骨骼. 例如你可能需要你的角色的頭注視3d空間的某個點. 這個活最好讓指令碼來幹. 幸運的是, Unity做這個很容易. 在Unity 中所有骨骼來驅動蒙皮網格(skinned mesh)的變換(Transforms). 因而你可以給角色的骨骼寫指令碼,就和其他GameObject一樣.

很重要的一點是動畫系統updates the Transforms 是在Update() function呼叫之後  ,LateUpdate() function 呼叫之前. 因而如果你要呼叫 LookAt() function 你應該do that in LateUpdate() to make sure that you are really overriding the animation.

布娃娃系統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這也意味著如果遊戲執行速率高於原始製作速率, 動作事實上看起來會更平滑流暢.

對絕大多數應用場合,  Unity對變化幀速的取樣我們無需對其進行干預. 可是, 如果你的某個遊戲邏輯所依賴的動畫變化或道具(transforms or properties)結構十分特殊, 那你必須知道這一點.  舉例說, 如果你有一個動畫是把一個物體30幀內從 0旋轉到180度, 你想從程式碼中得知什麼時候動畫完成一半, 你不能寫一段條件語言來檢查現在旋轉值是不是90度. 因為 Unity 依照遊戲的變化速率來對動畫取樣, 它可能在旋轉快到90度時進行取樣, 或者是剛好過90度的時候取樣. 如果你需要通報動畫中一個特殊點到達時, 你可以使用 AnimationEvent 來替代.

同樣需要注意的是變化的幀速取樣結果, 一個使用WrapMode.Once 模式重放的動畫的取樣不一定是精確的最後一幀( last frame). 在遊戲中很有可能是剛好結束前的某一幀, 在下一幀時間可能超過動畫的長度, so it is disabled 和 not sampled further. 如果你需要動畫的最後一幀取樣精確,你可以使用WrapMode.ClampForever. 如果是那樣的話動畫將不停的對最後一幀進行取樣直到你自己停止動畫.

相關推薦

Unity3D教程動畫融合動畫動畫混合附加動畫程式動畫動畫取樣

原帖地址:http://www.unitymanual.com/5323.html 動畫指令碼 Animation Scripting Unity's 動畫系統允許你建立一個漂亮的動畫蒙皮角色,動畫系統支援動畫融合,混合,新增動畫,步調週期時間同步.動畫層,控制動畫回

Unity3D教程學習Socket

這個例子是用Socket的TCP協議做的,當然也可以用UDP和TCPListener來做。沒用到多執行緒,其實就是為了看看裡面的一些函式而已。Server.cs: using UnityEngine; using System.Collections; usin

UE4 第一人稱射擊製作流程13(圖文)完善AI 機器人 Robot 死亡動畫融合---從正常狀態到死亡動畫融合後的播放條件

不廢話,直接開始,稍微有點繞,你們多操作,多思考就明白了, 前提條件先明確:動畫藍圖要去角色藍圖裡獲取函式等相關資料,需要純函式或者非純函式的建立和橋接(我是這樣理解的) 這一部分主要就是獲取Health小於等於0後播放死亡動畫,開始製作: 1、開啟Robot_Character,建立函式I

UE4 第一人稱射擊製作流程12(圖文)為AI 機器人Robot新增死亡動畫融合

接上之前的,人物受傷已經制作完畢,接下來製作死亡動畫融合,為後續死亡做準備; 1、開啟Robot_Animi動畫藍圖:下圖為之前製作好的動畫 2、現在開始新增死亡動畫融合,先建立一個新的狀態機:命名為Alive_Dead 3、斷開之前的,把新的狀態機連線上: 4、開啟Alive_Dea

原生webgl學習(八) WebGL實現動畫平移旋轉

筆者在前面的文章主要是針對二維的靜態圖形進行開發;但有時候我們需要模型動起來,就像真實世界中的一切運動變化一樣。場景如果不是動態的,那麼可想而知,我們的世界是多麼枯燥乏味。為了讓我們開發的圖形應用看上去更加高大上,這一節筆者將和大家一起做一個動畫的例子;本節的內容用到了前面文

Java自學之路-Java中級教程-12SpringMVC的三架構模型表現控制

MVC即Model、View、Controller三者的縮寫。Model為模型層,View為表現層,Controller為控制層。其中M處於最底層,V在最上層,中間層為Controller。比如使用者訪問網站,首先接觸的是View,即是網頁。通過訪問網頁的url,就會傳到Co

Unity---動畫系統學習(6)---Avatar Mask動畫融合Layers動畫分層IK反向動力學

ont 技術 分層 當前 pri layers mage 父節點 改變 1. 介紹 Avatar Mask(動畫融合) 前面我們一直介紹的都是動畫混合,一般用於解決邊跑邊轉彎的問題。而動畫融合一般用於解決例如邊跑邊揮手的問題。 簡單說就是讓跑步去控制腿的骨骼,揮手控制手的

手動動畫(9.2 圖時間)

void ner pda horizon aps splay container load set 手動動畫 timeOffset一個很有用的功能在於你可以它可以讓你手動控制動畫進程,通過設置speed為0,可以禁用動畫的自動播放,然後來使用timeOffset來來回顯

Arduino教程MPU6050的數據獲取分析與處理

6.5 校準 詳細 度量 運行時 操作 new 進行 intra Arduino教程:MPU6050的數據獲取、分析與處理 轉載 摘要 MPU6050是一種非常流行的空間運動傳感器芯片,可以獲取器件當前的三個加速度分量和三個旋轉角速度。由於其體積小巧,功能

以太坊教程搭建環境編寫編譯一個智能合約

以太坊教程 以太坊 以太坊開發 智能合約 區塊鏈 區塊鏈開發 solidity 本以太坊教程主要是介紹:搭建一個開發環境、編寫編譯一個智能合約。 以太坊是什麽 以太坊(Ethereum)是一個開源的有智能合約功能的公共區塊鏈平臺。通過其專用加密貨幣以太

VPS搭建SS教程VPS購買使用網絡優化,SS的搭建以及使用

oid 使用 root 保存 電腦配置 添加 引導 cts .html 下面的SS/SSR教程也是針對新手,從購買VPS,登錄VPS,對VPS的網絡進行優化(可以輕松看youtube的2k、4k),搭建SS/SSR,使用SS/SSR等。 下面以HiFormance提供的KV

Java8系列教程Java8編程入門面向對象編程高級編程核心設計模式 DAO設計模式

線程與進程 lamda java程序 thread類 pat 調用 watermark image fab Java8系列教程:Java8編程入門、面向對象編程、高級編程、核心設計模式 —— DAO設計模式01_《Java8編程入門》02001_JAVA發展簡介02002

【mpich2】圖文教程mpich2的安裝配置測試vs配置命令列測試(沒有使用)

轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/83549093 【安裝mpich2】 1、開啟“mpich2-1.4.1p1-win-ia32.msi。 2、點選“Next”。 3、點選“N

unity animator動畫融合時的上下半身速度分離控制

遊戲中要實現一邊走一邊攻擊, 移動還分八方向的,所以使用了半身混合。 Animator 半身混合的處理,可以另外看資料。   簡單來說 就是分2層:0層 播放基礎移動動作,比如“Run”, 1層設了Mask(配置了上半身節點),weight設1(會完全覆蓋0層的上半身動作),播

Git使用教程最詳細最傻瓜最淺顯真正手把手教!

作者:塗根華 原文出處:https://www.cnblogs.com/tugenhua0707/p/4050072.html 導讀:因為教程詳細,所以行文有些長,新手邊看邊操作效果出乎你的預料。GitHub雖然有些許改版,但並無大礙。 一:Git是什麼?    

HTML5 Canvas 教程曲線

三、曲線 Curve   3.1圓弧 Arc   通過呼叫上下文物件的arc()方法可以在HTML5畫布上繪製圓弧。圓弧由中心點、半徑、起始角、結束角和繪圖方向(順時針或逆時針)定義。同時可以用lineWidth、strokeStyle和lin

HTML5 Canvas 教程線條

二、線條Lines   2.1直線 Line   要在畫布上繪製線條,可以通過呼叫:beginPath()、moveTo()、lineTo()和stroke()方法來實現。 首先,我們可以使用beginPath()方法來宣告我們即將繪製一個新的路徑。

HTML5 Canvas 教程畫布

一、HTML5畫布 HTML5 Canvas   1.1畫布元素Canvas Element   HTML5 Canvas元素是類似於<div>、<a>或<table>標記的HTML標記,

HTML5 Canvas 教程形狀

五、形狀 Shapes   5.1自定義形狀 Custom Shape   若要用HTML5畫布繪製自定義形狀,可以建立一個路徑,然後呼叫closePath()方法關閉它。可以使用lineTo()、arcTo()、quadraticC

HTML5 Canvas 教程路徑

四、路徑 Paths   4.1路徑 Path   在HTML5畫布上繪製路徑,可以通過連線多個子路徑(曲線)實現。每個子路徑的結束點成為新的路徑的上下文點。我們可以使用lineTo()、arcTo()、quadraticCurveTo()和b