1. 程式人生 > >Unity3D中角色的動畫指令碼的編寫

Unity3D中角色的動畫指令碼的編寫

已有好些天沒寫什麼了,今天想起來該寫點東西了。這次我所介紹的內容主要是為了配合我前面所寫的角色運動控制有關的文章,那就是動畫。這是一個很複雜的概念,今天,我就把我所理解的有關動畫方面的觀點跟大家說說,不對的地方請大家指出,在下萬分感謝。
老實說,我學Unity時,角色控制真的是一個難點,尤其是動畫方面。想要在Unity中控制好一個角色且讓這個角色的動作協調,不是一個簡單的問題,需要我們深入理解其原理。只有這樣,我們才有能力寫一套精湛的角色控制指令碼。Unity裡面的動畫系統相當複雜(也許是我的程度不夠吧),我們不要期望自己不用將Unity動畫系統的一些原理搞清楚就能夠寫出一套很棒的角色控制指令碼,這是很愚蠢的。僅僅只是角色移動就播放跑步的動畫,角色停下來就播放站立的動畫,具有這種想法的程式設計師應該注意一下了。

那麼怎麼開始呢?我認為我們必須瞭解一些基本的概念。首先我們來了解一些基本的知識。首先是動畫的匯入。相信大部分讀者在讀本帖之前就已經對動畫的匯入有一定的瞭解了,這裡我可能會從頭開始講解,因為個人程度不同嘛。一般角色動畫是在三維軟體中設計好了之後,再匯入到unity3d中去的,且檔案格式一般是*.FBX。Unity3D中匯入角色動畫的方式主要有兩種,這兩種方式分別如下:
1.分割動畫。美術在三維軟體中對角色的動作設計完成之後將所有動畫集中在一個FBX檔案上。我們只需知道其製作的動畫片段的個數與其對應的幀數就可以對儲存在這個FBX檔案上的動畫進行準確的分割。詳細過程官方文件上寫的很清楚,我們只需要按部就班的執行就行。但是要注意一點,我們可以在分割動畫的時候會遇到這樣一個選項:WrapMode,圖如下:






這個WrapMode(迴圈模式)很重要,預設狀態下系統選擇的是Default,你可以調節其為其他選項,比如Loop。我們也可以利用指令碼來動態的操作它。關於其用法,我們會在後面的程式碼中得以體現。

2.多重動畫檔案。這是一個很方便的動畫匯入方法。在專案中,美術有可能將動畫資料與模型分開製成FBX檔案,那麼此時我們只需找到動畫的FBX模型,對它們以一個通用的方式命名即可。即"模型名@動畫名",例如一個模型的名字叫做gam,並且這個模型有一個名為“idle”的動畫的FBX檔案,那麼我們可以將這個FBX模型的名字命名為:
"[email protected]"。需要注意的是這個根模型中的各個動畫的迴圈模式是Default,而且在Inspector面板中無法修改,只能在指令碼中修改,有點坑吧。而且方式二中的檔案佔用大小對於方式一來說確實增大不少,這對於移動裝置類遊戲來說確實是一件必須斟酌的事情。望讀者務必注意一下。



瞭解完這些之後,我們該重點的談一談Unity裡面的與動畫相關的API了,重點有以下三個:Animation,AnimationClip,AnimationState。這次我們先看一下Animation這個類,我估計這次還講不完,如果是這樣,那我就儘量講得多一點吧。

Animation,官方是這樣介紹的:The animaiton component is used play back animations.翻譯過來就是:動畫租金按是被用來播放動畫集合的。說到這裡,談到了元件,對沒錯,這個類對應的就是我們的Animation元件。我們將Project面板下的任何一個FBX模型拖拽到Hierarchy面板中,你會在其對應的Inspector面板中發現其被自動添加了一個Animation元件,只不過其動畫片段的數量預設為0。你可以調節這個動畫的Size,然後從Project面板中找到相應的動畫片段,此動畫片段截圖如下:




動畫片段,即AnimationClip,實際就是上圖中的那個白色右下角有個圓形的idle檔案。你可以將這個動畫片段拖拽到Animation元件中的Animations下面,前提是其Size不為0,如下圖: 



下面我們來深入瞭解一下這個元件在指令碼中的運用,首先我們看一下這個類的變數: 



第一個變數是指的這個Animation元件的預設播放的動畫片段。第二個指的是該動畫元件中預設的動畫片段是否在遊戲執行時自動播放。第三個變數很重要,我們可以用指令碼來控制所有動畫片段的迴圈狀態,比如我們可以這樣寫 :
animation.wrapMode = WrapMode.Loop; 注意,小寫的animation指的是該指令碼附著的GameObject上的Animation元件。這句程式碼的功能是將該GameObject身上所有的動畫片段的播放方式設定為迴圈播放。且可以再後續的指令碼中進行相應的修改。那麼我們有必要了解一下這個變數的型別:WrapMode。我截了一個圖,如下:


WrapMode主要是用來對動畫片段的播放模式來進行修改的,這五個變數代表了5中播放模式。第一個Once,後面的解釋是這樣的:當這個動畫片段播放到了結尾,如果程式沒有修改它的wrapMode,那麼這個動畫片段將會自動停止播放,而且其此時播放的幀數被重置為第一幀,也就是該動畫片段的開頭。此播放方式可以應用在射擊類動畫片段的wrapMode中。第二個是Loop,我們應該是比較熟悉了吧。如果程式沒有修改它的wrapMode,該動畫片段播放完最後一幀之後並不會停止,而會回到第一幀並重復播放,知道當前的動畫狀態的改變。第三個變數是PingPong,意思是噹噹前動畫片段播放完最後一幀之後,如果程式沒有修改它的wrapMode,將隨機的在第一幀與最後一幀之間來回播放。第四個變數我們之前遇到過,在上面的動畫匯入方式中,如果是以分割動畫的匯入方式,那麼預設每個動畫片段的wrapMode為WrapMode.Default,即讀取預設的設定,不過可以在Inspetor面板中修改。但是如果是多重動畫檔案的匯入方式,那Unity連給你在Inspector中修改的機會都不給你,此時你只能在指令碼中進行動態修改其wrapMode。最後一個變數,ClampForever。如果當前播放的動畫的wrapMode的值為WrapMode.ClampForever,那麼當這個動畫片段播放完最後一幀時,如果程式沒有修改它的wrapMode,那麼它將會一直播放這個動畫狀態的最後一幀。除此之外,我們還可以在官方的CharacterAnimation工程中發現這樣一個變數:WrapMode.Clamp,後來經我驗證,發現這個變數就是WrapMode.Once。如果讀者不信的話,可以準備一個角色。加入這個角色具有名為“idle”(其他也行)的動畫片段,那麼我們可以寫這樣一個指令碼來驗證一下我們的猜想:

using UnityEngine;
using System.Collections;

public class TestWrapMode : MonoBehaviour {

// Use this for initialization
void Start () {
animation.Stop();//禁用Animaton元件中的Play Automatically。
animation["idle"].wrapMode = WrapMode.Clamp;//設定名為idle的動畫片段的wrapMode屬性為WrapMode.Clamp。

}

// Update is called once per frame
void Update () {

if(animation.IsPlaying("idle")){//如果當前有播放idle動畫那麼就執行下面

Debug.Log(animation["idle"].wrapMode);
}

if(Input.GetKeyDown(KeyCode.A)){

animation.CrossFade("idle");//淡入淡出名為idle的動畫。
}
}
}

整個指令碼非常簡單。我們將這個指令碼繫結在我們準備好的角色身上,當我們按下“A”鍵時,會在Console上列印idle的wrapMode屬性,那麼該屬性會是什麼呢?


果然是Once,哎,奇怪了,不是有一個Once嗎?怎麼還要加個Clamp呢?估計是當時設計API時出現的一些歷史遺留問題吧。不必管它,我們只需知道這個Clamp到底屬於那種效果就行了。
好了,WrapMode這個類介紹完了,下面我們該繼續介紹Animation這個類。讀者可能覺得我應該結合具體工程來講解這些知識,其實不然,如果你連最基本的概念都半生不熟的話,就不要指望寫出好的控制指令碼。接下來我儘量挑選一些重要的屬性和函式來進行講解。


類:Animation
屬性:
isPlaying 角色此時是否在播放動畫?
this[string name] 這個屬性非常重要,他的返回值型別是AnimationState,我們叫他動畫狀態。
剩下的幾個變數一般很少用到,讀者感興趣的話自己可以研究一下,比如animatePhysics,是用來結合運動學剛體來實現的。culling Type這個屬性你可以在Inspector面板中的Animation元件中看到,有幾個選項可選,那幾個選項讀起來也不難,這裡我也就不多說了,接下來我們來看幾個重要的函式:


1.Stop( ) 顧名思義,就是停止所有當前正在播放的動畫。

2.Rewind (string AnimationName) 導播名為AnimationName的動畫片段。

3.Sample() 在當前狀態對動畫進行取樣,說實話,這個函式我還真沒用過。

4.IsPlaying( string AnimaitonName ) 這個函式的拼寫和上面講到的isPlaying屬性是一樣的,只是該函式的首字母是大寫的。如果當前正在播放名為AnimationName的動畫,那麼此函式則返回***e,否則為false。這是一個非常重要的函式。我至今沒發現Unity裡面的動畫相關的類中有一個函式或者屬效能夠取得當前正在播放的動畫名稱,後來我才發現這個是得不到的,後面我會說明原因的。

5.Play( string AnimationName )
沒有任何混合的播放名為AnimationName的動畫片段。老實說,現在的動畫如果不混合,真的沒什麼看頭,所以這個函式一般我們也不用。

6.CrossFade( string animation , float time , PlayMode mode )
這個函式我們得注意了,它具有淡入名為animation的動畫並淡出當前正在播放的動畫的效果,這種效果真的很棒,他使我們的動畫播放更為平滑。並且這個函式還有兩個過載的方法。比如我們角色的Animation元件中有一個名為“Walk”的動畫片段 。那麼我們要淡如這個動畫片段就有一下三種 寫法:
1. animation.CrossFade( "Walk" ); 以預設方式淡入名為“Walk”的動畫,
2. animation.CrossFade( "Walk",0.3f );在0.3秒左右淡入名為“Walk”的動畫;
3. animation.CrossFade( "Walk",0.3f,PlayMode.StopSameLayer ) 這句程式碼與上句是一樣的,只是第二句省略了第三個引數。這個引數的型別為PlayMode,裡面有兩個屬性:PlayMode.StopSameLayer,StopAll,第一個屬性
表示停止同一層的動畫,當函式中沒有此引數時,預設用的就是這個屬性;第二個屬性表示停止所有的動畫。

 還剩下幾個函式,有點晚了,下一篇我在介紹吧。這篇文章我確實是費了不少心思的。接下來的幾篇我會盡量將我的心得奉獻給大家,對此感興趣的讀者不妨留意一下

本文來自:http://www.narkii.com/club/thread-267966-1.html

相關推薦

Unity3D角色動畫指令碼編寫

已有好些天沒寫什麼了,今天想起來該寫點東西了。這次我所介紹的內容主要是為了配合我前面所寫的角色運動控制有關的文章,那就是動畫。這是一個很複雜的概念,今天,我就把我所理解的有關動畫方面的觀點跟大家說說,不對的地方請大家指出,在下萬分感謝。老實說,我學Unity時,角色控制真的

Unity3D Generic 動畫導入設置和 Root Motion 之間的關系

出現 efi 主題 之前 理解 就會 runt 設置 clip Unity3D 的 Mecanim 動畫系統可以直接復用 3DS MAX 中制作的動畫文件中的位移,這個就是通過 applyRootMotion 來達成的,我們只需要在使用 Animator 控制動畫播放的同時

Unity3D 物體移動指令碼小記

Uinty3D 中物體移動指令碼小記 最近幾天在Unity官網看了官方提供的教程,自己也實驗了一下,發現幾個不同的專案中,指令碼中對物體移動的實現方式並不相同。 using UnityEngine; public class PlayerMoveContr

Unity3D Generic 動畫匯入設定和 Root Motion 之間的關係

注意 Root Motion 與 Rigidbody.Velocity 屬性的關係,如果有兩個動畫 A 和 B,播放 A 動畫的時候,希望 A 動畫應用 Root Motion,而在播放 B 動畫的時候不想應用 Root Motion,那麼就直接在切換到動畫 B 的時候,將 Animator 的 apply

Python模擬黑客帝國影片的終端動畫指令碼

前言 翻閱Github發現一個模擬黑客帝國終端動畫的效果!只需要安裝以後執行簡單命令就好!效果圖: 安裝 採用Python包管理工具pip安裝即可: pip install git+https://github.com/will8211/unimatrix.g

unity3d JavaScript指令碼和C#指令碼的相互呼叫

本人親測unityd5.56版本,開啟Unity在Project檢視下新建資料夾Standard Assets。新建JavaScript指令碼:testJs,C#指令碼testCs. testJs程式碼如下: function OnGUI()     {       

Unity3D - LeanTouch例子的各指令碼

1 物體選擇 1.1 LeanSelect This component allows you to select LeanSelectable components 此方法允許你選擇物體(需要在待選物體上掛上LeanSelectable指令碼) 1.2 LeanSelectable

unity3d水草海草搖動效果頂點動畫材質

因為最近要嘗試在untiy3d做寫實海底的效果,上圖為版本5.5裡面實現的效果 為了讓畫面更加逼真,海底植物必不可少 然而海底的海藻海草之類需要加上動畫就比較麻煩了 一般的骨骼動畫加起來比較麻煩,而且效果比較單調,消耗也很大 更不用說動力學解算了,通常時間長,而且烘焙成頂

在原始碼環境編譯Android studio專案時的mk指令碼編寫

1、Main專案是主工程,下面有名為app的專案       CommonLib是庫工程,下面有名為lib的專案       Main專案會用到CommonLib庫。 2、原始碼環境中兩個專案是在同一個目錄下,平級的。Android.mk分別在各自的根目錄下。 3、參考

Unity3D三種呼叫其他指令碼函式的方法

第一種,被呼叫指令碼函式為static型別,呼叫時直接用  指令碼名.函式名()。很不實用…… 第二種,GameObject.Find("指令碼所在物體名").SendMessage("函式名");  此種方法可以呼叫public和private型別函式 第三種,Ga

Unity周邊——在Unity3D使用DragonBones動畫

開始 2、我這裡的軟體環境是Windows平臺、Unity版本2017.3.0。需要下載Windows版,然後進行傻瓜式安裝。當前DragonBonesPro最新版本為5.6.0。 3、安裝結束後,開啟軟體。首次使用時,會預設開啟歡迎頁。 4、點選開啟紅框所

Unity3d使用自帶動畫系統製作下雨效果

之前看了以前版本的unity3d demo AngryBots ,覺得裡面的下雨效果不錯,剛好前段時間學習了,寫出來跟大家分享下,直接開始。 使用自帶動畫系統製作下雨效果。 先製作下雨的雨滴漣漪。 步驟1: 在project中新建資料夾,命名為rainFX。將圖片

unity3d使用精靈sprite建立並控制2d動畫

這裡明確幾個概念 Animation是每一個動畫,動畫本身不能獨立在場景中播放 Animator是動畫控制器,一個動畫控制器裡可以包含多個動畫,根據條件選擇播放哪一個動畫 精靈Sprite上掛載Animator動畫控制器來播放動畫 crtl+6開啟animation編輯面板

Unity3D使用C#呼叫C++編寫的DLL

前言 Unity3D是一款非常優秀的遊戲引擎,可以使用C#作為指令碼語言進行程式設計。但是有的時候我們需要執行一些第三方的程式,例如C++實現的一些演算法。我們需要將C++的程式碼以DLL的形式嵌入到

Unity3D通過Animator動畫狀態機獲取任意animation clip的準確播放持續時長

Unity3d 4及之前的版本中動畫的播放用的animation,可直接獲取其播放持續長度。但5.x及以後的版本中都是用animator來播放動畫了。 While Mecanim is recommended for use in most situations, U

windowsbat指令碼編寫

#前言 大家都知道python的便利,但是如果這臺計算機沒有裝python環境怎麼辦,這時為了做一些重複性的工作,就不得不用cmd來編寫一些簡單的指令碼。 希望對大家有點幫助,文末有一些實用的指令碼 ###基本命令 可以使用windows+R調出執行框,輸入cm

Unity3Dtolua的“安裝部署和使用“教程

替換 部署 ref 比對 text asset gin 系統 .com 棄坑Cocos2d-x,轉戰Unity3D 考慮到項目一定會使用熱更,花了不少時間比對了lua的支持方案,最後定為tolua,原因不解釋。 俗話說,萬事開頭難,中間難,最後難……我反正是沒有找到如何安裝

Unity3D的Coroutine具體解釋

腳本 end have bre nes until 重寫 pst .net 本文太亂,推薦frankjfwang的:全面解析Coroutine技術 Unity中的coroutine是通過yield expression;來實現的。官方腳本中到處會看到這種代碼。

Unity3dSendMessage 用法

req unity3 move 忽略 function java ear option 自動 Message相關有3條指令:SendMessage ("函數名",參數,SendMessageOptions) //GameObject自身的ScriptBroadc

(轉)Unity3D移動物體位置的幾種方法

多種方式 移動 2.4 包括 簡介 調用 在外 blank targe 1. 簡介 在unity3d中,有多種方式可以改變物體的坐標,實現移動的目的,其本質是每幀修改物體的position。 2. 通過Transform組件移動物體 Transform 組件