最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

Unity Animation -- 使用Animator控制動(dòng)畫

2023-04-04 20:59 作者:vivo119  | 我要投稿

? ? ? ? 在很多實(shí)際場景中,我們經(jīng)常需要根據(jù)特定的事件(比如玩家輸入,敵人受到攻擊等)來播放不同的動(dòng)畫。這需要我們了解一下Animator,Animator Controller和基礎(chǔ)的動(dòng)畫狀態(tài)機(jī)。

創(chuàng)建一個(gè)開門的動(dòng)畫

? ? ? ? 首先我們來創(chuàng)建一個(gè)簡單的開門動(dòng)畫,示例中的門的模型來自官方教程。其實(shí)我們也可以用一個(gè)簡單的Cube調(diào)整一下做成門的形狀來做。無論是哪種方式,我們首先需要檢查一下這個(gè)游戲物體的pivot point。一個(gè)pivot point是物體進(jìn)行移動(dòng)的基準(zhǔn)點(diǎn)。對于門來說,這個(gè)點(diǎn)非常重要。如果pivot點(diǎn)設(shè)置不對,則開門動(dòng)畫會(huì)看起來非常奇怪(比如門沿著自身中軸線旋轉(zhuǎn),當(dāng)然,如果你是要制作旋轉(zhuǎn)門動(dòng)畫就另說,示例中是一個(gè)普通的門)。

? ? ? ? 1. 首先,選中門對應(yīng)的游戲物體。此時(shí)Unity編輯器中會(huì)出現(xiàn)移動(dòng)widget,如果這個(gè)widget的位置處于游戲物體正中心,如下圖:


? ? ? ? ?2. 我們點(diǎn)擊Toggle Tool Handle Position按鈕(上圖左上角紅框處),將它從Center改為Pivot


? ? ? ? ?3. 在Animation編輯器中,點(diǎn)擊Create按鈕,創(chuàng)建一個(gè)新的動(dòng)畫片段,我們將其命名為Door_Open并保存


? ? ? ? ?4. 在Animation編輯器中,點(diǎn)擊Record,然后點(diǎn)擊Add Property,添加Transform -> Rotation屬性


? ? ? ? ?5. 將Playhead移動(dòng)到1:00處(第二個(gè)關(guān)鍵幀),然后調(diào)整一下門的旋轉(zhuǎn)角度,將門的Inspector里的Transform -> Rotation里的Y改成90


? ? ? ? ?6. 預(yù)覽一下開門動(dòng)畫,沒問題后再次點(diǎn)擊Record退出Recording模式。

? ? ? ? ?7.? 在工程文件窗口中,找到剛剛創(chuàng)建的Door_Open動(dòng)畫文件,點(diǎn)擊后,在Inspector窗口中,禁用掉Loop Time。禁用這個(gè)選項(xiàng)后動(dòng)畫只會(huì)播放一次,而不是無限循環(huán)。


?Animator Controller

? ? ? ? 再次選擇Door游戲物體,在Inspector中我們可以看到出現(xiàn)了一個(gè)新的Animator組件。對于一個(gè)選中的游戲物體,當(dāng)我們第一次為其創(chuàng)建動(dòng)畫片段時(shí),Unity會(huì)自動(dòng)為它創(chuàng)建一個(gè)Animator組件。


? ? ? ? ?Animator負(fù)責(zé)為游戲物體分配動(dòng)畫。但它并不控制實(shí)際的動(dòng)畫片段,這個(gè)任務(wù)交給了Animator Controller,這個(gè)也是在第一個(gè)動(dòng)畫片段創(chuàng)建時(shí)自動(dòng)創(chuàng)建的。在Animator組件中的Controller這一欄中,可以看到有一個(gè)名為Door的Animator Controller(在保存動(dòng)畫的目錄中,一般為Animations目錄,下面也有一個(gè)同樣名字的Door文件)。

? ? ? ? 1. 在工程文件窗口中,選中Door這個(gè)文件,將其重命名為Door_Controller


? ? ? ? ?2. 雙擊這個(gè)文件,打開Animator窗口


? ? ? ? ?3. 為了方便演示,將Animator窗口拖動(dòng)到工程窗口處


? ? ? ? ?4. 在場景中選中Door游戲物體,然后點(diǎn)擊Play進(jìn)入游戲模式


? ? ? ? ?當(dāng)場景進(jìn)入Play模式后,可以看到門被打開了,同時(shí),我們會(huì)看到Animator窗口中的Door_Open動(dòng)畫下方有一個(gè)藍(lán)色的進(jìn)度條開始慢慢填滿,這表示Door_Open動(dòng)畫片段的播放過程。Animator窗口中會(huì)實(shí)時(shí)地顯示當(dāng)前正在播放的動(dòng)畫片段以及動(dòng)畫片段播放進(jìn)度。

動(dòng)畫狀態(tài)機(jī)

? ? ? ? Animation Controller運(yùn)行在一種叫做狀態(tài)機(jī)(State Machine)的特殊系統(tǒng)上。狀態(tài)機(jī)會(huì)跟蹤一個(gè)物體所能執(zhí)行的所有可能的動(dòng)作,并且根據(jù)當(dāng)前的情況(狀態(tài),state)選擇合適的動(dòng)作。對于當(dāng)前狀態(tài)的控制邏輯,一般是通過腳本來控制。狀態(tài)機(jī)處理的從一個(gè)動(dòng)作轉(zhuǎn)到另一個(gè)動(dòng)作的過程,叫做轉(zhuǎn)換(Transition)。

? ? ? ? 為了更好地理解狀態(tài)機(jī)是如何工作的,我們以案例里的門為例子,它可以執(zhí)行的動(dòng)作有開門和關(guān)門兩種。

? ? ? ? 因此門可能處于的狀態(tài)有:


  • ? ? ? ? 正在開門過程中(Currently Opening)


  • ? ? ? ? 正在關(guān)門過程中(Currently Closing)


  • ? ? ? ? 打開狀態(tài)(Currently Open)


  • ? ? ? ? 關(guān)閉狀態(tài)(Currently Close)

? ? ? ? 接下來我們畫出這些狀態(tài)之間的關(guān)系:


? ? ? ? ?門的默認(rèn)狀態(tài)處于關(guān)閉狀態(tài)。當(dāng)玩家足夠靠近門時(shí),狀態(tài)機(jī)會(huì)切換到正在開門的狀態(tài),然后會(huì)切換到打開狀態(tài)。在玩家離開之前,門會(huì)一直處于打開狀態(tài)。玩家離開后,門會(huì)進(jìn)入正在關(guān)閉狀態(tài),然后切換到關(guān)閉狀態(tài)。此時(shí)狀態(tài)機(jī)又回到了初始狀態(tài)。

? ? ? ? 基于此,我們可以看到有兩種轉(zhuǎn)換(transitions)需要一些邏輯輸入(檢測玩家靠近和遠(yuǎn)離門),有兩種狀態(tài)會(huì)自動(dòng)轉(zhuǎn)換到下一個(gè)狀態(tài)(正在開門轉(zhuǎn)換到開門,正在關(guān)門轉(zhuǎn)換到關(guān)門)。

創(chuàng)建默認(rèn)動(dòng)畫狀態(tài)

? ? ? ? 前面小節(jié)中,我們創(chuàng)建的Door_Open動(dòng)畫,只要場景開始運(yùn)行就會(huì)自動(dòng)播放。這不是我們想要的效果,造成這個(gè)問題的原因是,當(dāng)前只有這個(gè)動(dòng)畫和門關(guān)聯(lián),在添加這個(gè)動(dòng)畫時(shí),Unity的Animation Controller自動(dòng)將其設(shè)置為了默認(rèn)狀態(tài)。接下來我們來解決一下這個(gè)問題。

? ? ? ? 1. 在Animator的工作區(qū)中(背景是網(wǎng)格,包含了各種狀態(tài)的區(qū)域),點(diǎn)擊右鍵并選擇Create State -> Empty,創(chuàng)建一個(gè)空狀態(tài)

? ? ? ? 2. 選擇新創(chuàng)建的節(jié)點(diǎn),在Inspector面板中,將它的名字從New State改為Closed

? ? ? ? 3. 右鍵點(diǎn)擊Closed狀態(tài),然后選擇“Set as Layer Default State”


?????????我們可以看到,現(xiàn)在Closed狀態(tài)變成了橙色,并且Entry節(jié)點(diǎn)指向了它。Entry節(jié)點(diǎn)和Closed節(jié)點(diǎn)之間的橙色線表示了一個(gè)轉(zhuǎn)換(transition)。Entry節(jié)點(diǎn)是狀態(tài)機(jī)開始運(yùn)行時(shí)所處的第一個(gè)節(jié)點(diǎn),在場景開始運(yùn)行的時(shí)候會(huì)自動(dòng)運(yùn)行Entry節(jié)點(diǎn)。

? ? ? ? 4. 再次點(diǎn)擊運(yùn)行按鈕,看看門的行為有什么差異。

實(shí)現(xiàn)開門狀態(tài)轉(zhuǎn)換

? ? ? ? 下一步,我們來實(shí)現(xiàn)檢測玩家并切換到開門動(dòng)畫的功能。要檢測玩家是否靠近到門,通常的邏輯是通過一個(gè)Trigger碰撞器加上腳本來實(shí)現(xiàn)。我們先完成狀態(tài)機(jī)部分的設(shè)置,增加腳本要使用的引用變量即可。

? ? ? ? 1. 右鍵點(diǎn)擊Closed節(jié)點(diǎn),選擇Make Transition。此時(shí)有一個(gè)白色的箭頭會(huì)出現(xiàn)在光標(biāo)處。

? ? ? ? 2. 選擇Door_Open節(jié)點(diǎn),讓這個(gè)箭頭和它連接起來。



? ? ? ? 3. 點(diǎn)擊運(yùn)行按鈕測試一下效果。

? ? ? ? ? ? ? ? 運(yùn)行過程中,我們可以看到,在Animation Controller中,首先會(huì)經(jīng)過Closed節(jié)點(diǎn)。當(dāng)Closed節(jié)點(diǎn)完成后,會(huì)立即調(diào)到Door_Oepn動(dòng)畫,隨后停在了開門動(dòng)畫上。為了避免Closed節(jié)點(diǎn)直接調(diào)到開門動(dòng)畫節(jié)點(diǎn),我們要在轉(zhuǎn)換條件上附加一些邏輯來做控制。要實(shí)現(xiàn)這個(gè)控制,我們需要使用狀態(tài)機(jī)參數(shù)(Parameters)參數(shù)是Animator內(nèi)部創(chuàng)建的變量,可以在Animator編輯器的左邊找到Parameters標(biāo)簽頁。

? ? ? ? 4. 選擇Parameters標(biāo)簽頁,在Parameteres列表的頂部,點(diǎn)擊“+”并且選擇Trigger(觸發(fā)器)


? ? ? ? ? ? ?Trigger參數(shù)會(huì)在它被腳本所修改時(shí)立即變化。

? ? ? ? 5. 將Trigger變量的名字設(shè)置為PlayerProximity,注意后面在腳本里引用這個(gè)變量時(shí),名字一定不要搞錯(cuò)了。

? ? ? ? 6. 選中Closed和Door_Open節(jié)點(diǎn)中間的帶白色箭頭線。然后在其Inspector中找到Conditions。

? ? ? ? 7. 在Condiditons列表底部,選擇“+”。由于目前只有一個(gè)參數(shù),PlayerProximity會(huì)自動(dòng)加到列表中。


? ? ? ? 8. 點(diǎn)擊運(yùn)行按鈕,運(yùn)行場景。

? ? ? ? 9. 在參數(shù)列表中,點(diǎn)擊PlayerProximity參數(shù)旁邊的單選按鈕,手動(dòng)觸發(fā)這個(gè)變量。


? ? ? ? 我們可以看到,當(dāng)PlayerProximity被修改后,狀態(tài)切換到了Door_Open并開始播放開門動(dòng)畫。

實(shí)現(xiàn)關(guān)門狀態(tài)轉(zhuǎn)換

? ? ? ? 接下來我們用類似的方法實(shí)現(xiàn)關(guān)門狀態(tài)。

? ? ? ? 1. 在Animator里選中Door_Open節(jié)點(diǎn),然后按Ctrl/Command + d復(fù)制一份這個(gè)節(jié)點(diǎn)。

? ? ? ? 2. 在Inspector中,將復(fù)制的節(jié)點(diǎn)的名字修改為Door_Close,并且將它的Speed參數(shù)設(shè)置為-1,這樣會(huì)讓動(dòng)畫的幀反向播放。?

? ? ? ? 3. 右鍵點(diǎn)擊Door_Open節(jié)點(diǎn),選擇Make Transition,然后將Door_Open和Door_Close節(jié)點(diǎn)連接起來。


? ? ? ? 4. 選擇這個(gè)新建的轉(zhuǎn)換(transition),在Condiditons列表中點(diǎn)擊“+”。同樣,PlayerProximity會(huì)自動(dòng)出現(xiàn)。

? ? ? ? 5. 點(diǎn)擊運(yùn)行按鈕,運(yùn)行場景,同樣我們使用PlayerProximity旁邊的單選按鈕,來測試先開門后關(guān)門的動(dòng)作是否正常。

? ? ? ? Animator中的Trigger參數(shù)在當(dāng)前轉(zhuǎn)換(從一個(gè)狀態(tài)切換到下一個(gè)狀態(tài))完成后,會(huì)立即失效。因此我們在開門和關(guān)門的時(shí)候,可以安全地復(fù)用這個(gè)參數(shù)。后面我們會(huì)用腳本來操作這個(gè)參數(shù)。

復(fù)位狀態(tài)機(jī)

? ? ? ? 到目前為止,我們以及實(shí)現(xiàn)了通過Animator參數(shù)來實(shí)現(xiàn)開門和關(guān)門的動(dòng)畫播放和相關(guān)狀態(tài)。但狀態(tài)機(jī)最后會(huì)停留在關(guān)門狀態(tài),這個(gè)過程只會(huì)發(fā)生一次。為了讓動(dòng)畫每次在PlayerProximity發(fā)生變化時(shí)還能正常表現(xiàn),當(dāng)關(guān)門動(dòng)畫播放完畢時(shí),我們要將動(dòng)畫狀態(tài)機(jī)復(fù)位到初始狀態(tài)。我們可以通過使用Exit節(jié)點(diǎn)來實(shí)現(xiàn)這個(gè)功能。當(dāng)狀態(tài)轉(zhuǎn)換到Exit節(jié)點(diǎn)時(shí),狀態(tài)機(jī)會(huì)自動(dòng)地切換到Entry節(jié)點(diǎn)。

? ? ? ? 1. 右鍵點(diǎn)擊Door_Close節(jié)點(diǎn),選擇Make Transition。

? ? ? ? 2. 點(diǎn)擊Exit節(jié)點(diǎn),連接Door_Close節(jié)點(diǎn)和Exit節(jié)點(diǎn)。


? ? ? ? 3. 點(diǎn)擊運(yùn)行按鈕,運(yùn)行場景

? ? ? ? ? ? 現(xiàn)在我們可以看到,當(dāng)Door_Close播放完成后會(huì)自動(dòng)轉(zhuǎn)換到Exit,然后再回到Closed狀態(tài)。這里我們還會(huì)注意到一點(diǎn),在我們修改了PlayerProximity的值之后到門被打開之間會(huì)有點(diǎn)延遲。這是因?yàn)槟J(rèn)情況下,在一個(gè)狀態(tài)節(jié)點(diǎn)執(zhí)行轉(zhuǎn)換之前,要先走完整個(gè)動(dòng)畫播放時(shí)間(Animator里狀態(tài)節(jié)點(diǎn)的進(jìn)度條可以直觀感受到這個(gè)時(shí)間)。我們可以選擇將禁用這個(gè)行為,讓切換到Door_Open的轉(zhuǎn)換立即發(fā)生。

? ? ? ? 4. 選擇Closed和Door_Open節(jié)點(diǎn)之間的轉(zhuǎn)換(transition),在Inspector中,禁用掉Has Exit Time。


? ? ? ? 6. 重新運(yùn)行場景,看看現(xiàn)在的效果。

?添加Trigger檢測碰撞器,用腳本控制PlayerProximity參數(shù)

? ? ? ? 前面我們通過手動(dòng)點(diǎn)擊PlayerProximity的方式來做狀態(tài)機(jī)的測試。接下來我們用一個(gè)Trigger碰撞器和一個(gè)腳本來實(shí)現(xiàn)對這個(gè)參數(shù)的動(dòng)態(tài)控制。關(guān)于普通的collider和tirgger collider的區(qū)別,本筆記不會(huì)討論,請自行參考網(wǎng)上資料。

? ? ? ? 1. 在Hierarchy中,點(diǎn)擊右鍵選擇Create Empty創(chuàng)建一個(gè)空游戲物體。

? ? ? ? 2. 將這個(gè)游戲物體命名為Door_Trigger。

? ? ? ? 3. 選中Door_Trigger,在Inspector中選擇Add Component,添加一個(gè)Box Collider。

? ? ? ? 4. 在Box Collider組件中,啟用“Is Trigger”。

? ? ? ? 5. 調(diào)整Box Collider的大小,讓其能夠覆蓋到門前后一片空間。

? ? ? ? 6. 編寫DoorTrigger腳本,并且將腳本添加到Door_Trigger游戲物體上。

? ? ? ? ? ? ?DoorTrigger腳本代碼如下:


? ? ? ? ? ? ?代碼意思很好懂,OnTriggerEnter/Exit函數(shù)中,檢測到Player進(jìn)入/離開Trigger Collider之后,會(huì)去修改PlayerProximity參數(shù)。?

? ? ? ? 7. 在Door_Trigger的Inspector中,將Door游戲物體拖動(dòng)到Door Trigger腳本里的Anim屬性方框中,這能夠?qū)oor的animator和腳本里的Anim參數(shù)關(guān)聯(lián)到一起(當(dāng)然,也可以直接在腳本里通過GetComponent方法獲取這個(gè)Animator)。


? ? ? ? 8. 運(yùn)行場景,控制Player進(jìn)入和離開Trigger Collider的區(qū)域,觀察結(jié)果(案例中有一個(gè)可用鍵盤控制的人物模型,我們也可以直接在場景中添加一個(gè)小球或立方體來代替,通過在Editor中拖動(dòng)這個(gè)物體來實(shí)現(xiàn)Trigger Collider的檢測)。


Unity Animation -- 使用Animator控制動(dòng)畫的評論 (共 條)

分享到微博請遵守國家法律
邯郸市| 崇义县| 五指山市| 博客| 南乐县| 平潭县| 乌恰县| 开原市| 沁阳市| 西安市| 田东县| 金溪县| 台东市| 肃宁县| 阿瓦提县| 普格县| 郴州市| 永康市| 长兴县| 北川| 尼玛县| 闵行区| 阿城市| 北京市| 舒城县| 衢州市| 吴忠市| 青州市| 龙岩市| 彭阳县| 临夏市| 陆丰市| 忻州市| 山东| 平乐县| 大庆市| 枣庄市| 大港区| 永修县| 新疆| 扶沟县|