經過上一節的操做,咱們不只建立了精靈的動畫,還設置了動畫的過渡條件,最終使得精靈得以按照咱們的意願,進入咱們所指定的動畫狀態。可是這其中還有一些問題。例如,咱們沒法使用鍵盤控制精靈當前要進入的動畫狀態,並且精靈也只是在原地播放動畫而已。但咱們但願精靈在進入到PlayerWalkingAnimation狀態時,位置應該發生改變。函數
要解決這些問題,就須要編寫腳本。也就是說,要使用腳原本實現動畫的播放控制,以及其它一些遊戲的邏輯。動畫
在Project視圖裏,新建一個文件夾,命名爲Scripts,在此文件夾裏新建一個C#腳本,命名爲PlayerStateController,而後爲此腳本添加下面的代碼:ui
01 using UnityEngine;spa
02 using System.Collections;orm
03 對象
04 public class PlayerStateController : MonoBehaviour教程
05 {遊戲
06 //定義遊戲人物的狀態事件
07 public enum playerStatesip
08 {
09 idle = 0, //表示空閒
10 left, //表示左移
11 right, //表示右移
12 }
13 //定義委託和事件
14 public delegate void playerStateHandler(PlayerStateController.playerStates newState);
15 public static event playerStateHandler onStateChange;
16 void LateUpdate ()
17 {
18 //獲取玩家在鍵盤上對A、D,或者左、右方向鍵的輸入
19 float horizontal = Input.GetAxis("Horizontal");
20 if(horizontal != 0.0f)
21 {
22 //若是按下的是左方向鍵,則廣播左移狀態
23 if(horizontal < 0.0f)
24 {
25 if(onStateChange != null)
26 onStateChange(PlayerStateController.playerStates.left);
27 }
28 //若是按下的是右方向鍵,則廣播右移狀態
29 else
30 {
31 if(onStateChange != null)
32 onStateChange(PlayerStateController.playerStates.right);
33 }
34 }
35 else
36 {
37 //廣播空閒狀態
38 if(onStateChange != null)
39 onStateChange(PlayerStateController.playerStates.idle);
40 }
41 }
42 }
將此腳本賦予Hierarchy視圖裏的Player對象。對於此腳本,有如下幾點須要說明:
q 腳本07行,定義了名爲playerStates的枚舉類型,此類型中定義了精靈的具體狀態;
q 腳本19行,會獲取玩家在鍵盤上對指定按鍵的輸入。不一樣的輸入值會直接致使精靈進入不一樣的遊戲狀態;
q 此腳本中定義的是一個能夠控制精靈當前所進入動畫狀態的類,也能夠認爲是一個管理類型的類,只負責向精靈「發號施令」,具體的實現過程不是這個類要考慮的;
上一小節裏,咱們使用腳本,定義了一個用於「發號施令」的類,而本小節將使用腳本定義一個「負責具體執行」的類。
在Project視圖裏的Scripts文件夾下,新建一個C#腳本,命名爲PlayerStateListener,爲此腳本添加下面的代碼:
01 using UnityEngine;
02 using System.Collections;
03
04 [RequireComponent(typeof(Animator))]
05 public class PlayerStateListener : MonoBehaviour
06 {
07 public float playerWalkSpeed = 3f; //表示精靈移動的速度
08 private Animator playerAnimator = null; //表示對象上的Animator組件
09 //表示精靈當前的動畫狀態
10 private PlayerStateController.playerStates currentState = PlayerStateController.playerStates.idle;
11 //對象可用時,加入到訂閱者列表中
12 void OnEnable()
13 {
14 PlayerStateController.onStateChange += onStateChange;
15 }
16 //不可用時,從訂閱者列表中退出
17 void OnDisable()
18 {
19 PlayerStateController.onStateChange -= onStateChange;
20 }
21 void Start()
22 {
23 //創建與對象上Animator組件的聯繫
24 playerAnimator = GetComponent<Animator>();
25 }
26 void LateUpdate()
27 {
28 onStateCycle();
29 }
30 //用於檢測當前所處的動畫狀態,在不一樣的狀態下將表現出不一樣的行爲
31 void onStateCycle()
32 {
33 //表示當前對象的大小
34 Vector3 localScale = transform.localScale;
35 //判斷當前處於何種狀態
36 switch(currentState)
37 {
38 case PlayerStateController.playerStates.idle:
39 break;
40 //向左移動
41 case PlayerStateController.playerStates.left:
42 transform.Translate(
43 new Vector3((playerWalkSpeed * -1.0f) * Time.deltaTime, 0.0f, 0.0f));
44 //角色將轉向
45 if(localScale.x > 0.0f)
46 {
47 localScale.x *= -1.0f;
48 transform.localScale = localScale;
49 }
50 break;
51 //向右移動
52 case PlayerStateController.playerStates.right:
53 transform.Translate(new Vector3(playerWalkSpeed * Time.deltaTime, 0.0f, 0.0f));
54 //角色將轉向
55 if(localScale.x < 0.0f)
56 {
57 localScale.x *= -1.0f;
58 transform.localScale = localScale;
59 }
60 break;
61 }
62 }
63
64 //當角色的狀態發生改變的時候,調用此函數
65 public void onStateChange(PlayerStateController.playerStates newState)
66 {
67 //若是狀態沒有發生變化,則無需改變狀態
68 if(newState == currentState)
69 return;
70 //判斷精靈可否由當前的動畫狀態,直接轉換爲另外一個動畫狀態
71 if(!checkForValidStatePair(newState))
72 return;
73 //經過修改Parameter中Walking的值,修改精靈當前的狀態
74 switch(newState)
75 {
76 case PlayerStateController.playerStates.idle:
77 playerAnimator.SetBool("Walking", false);
78 break;
79 case PlayerStateController.playerStates.left:
80 playerAnimator.SetBool("Walking", true);
81 break;
82 case PlayerStateController.playerStates.right:
83 playerAnimator.SetBool("Walking", true);
84 break;
85 }
86 //記錄角色當前的狀態
87 currentState = newState;
88 }
89
90 //用於確認當前的動畫狀態可否直接轉換爲另外一動畫狀態的函數
91 bool checkForValidStatePair(PlayerStateController.playerStates newState)
92 {
93 bool returnVal = false;
94 //比較兩種動畫狀態
95 switch(currentState)
96 {
97 case PlayerStateController.playerStates.idle:
98 returnVal = true;
99 break;
100 case PlayerStateController.playerStates.left:
101 returnVal = true;
102 break;
103 case PlayerStateController.playerStates.right:
104 returnVal = true;
105 break;
106 }
107 return returnVal;
108 }
109 }
將此腳本賦予Hierarchy視圖裏的Player對象,選中後者,而後在Inspector視圖裏,找到此腳本組件,發現裏面有一個屬性Player Walk Speed,如圖1-31所示。正如屬性名的含義,它能夠用於設置精靈的移動速度,而且值越大,精靈的移動速度越快。
圖1-31 腳本組件,及其屬性
對於此腳本,有如下幾點須要說明:
q 腳本10行,說明默認狀況下,精靈在遊戲開始時,所處的是Idle動畫狀態;
q 腳本12、17行定義的方法OnEnable()和OnDisable(),說明只有成爲訂閱者的對象纔會收到動畫狀態改變的消息;
q 腳本31行定義的方法onStateCycle(),能夠依據精靈當前所處的動畫狀態,修改精靈在場景中的位置屬性。例如,當精靈進入左移的動畫狀態時,就向左修改場景裏精靈的位置;
q 腳本65行定義的方法onStateChange(),用於真正修改精靈當前所處的動畫狀態,也就是經過設置Parameters中Walking的值,進而完成的精靈動畫狀態的切換;
q 腳本91行定義的方法checkForValidStatePair(),說明動畫狀態並不是能夠隨意轉換,這是爲了更加符合邏輯。例如,人能夠從「跑」的狀態過渡到「跑跳」的狀態,可是沒法從「走」的狀態過渡到「跑跳」的狀態。
q 腳本中44~49、54~59行的代碼應該被關注,由於它使得精靈實現了「轉身」。爲何這麼說呢?由於沒有它們的話,精靈會始終朝向一個方向,讀者能夠註釋掉它們並運行程序查看效果。精靈默認在遊戲場景裏的位置屬性,以及顯示效果如圖1-32所示。若是修改位置屬性裏Scale在X屬性上的值爲原來的負數,遊戲場景裏的精靈就會「轉身」,如圖1-33所示。
圖1-33 Scene和Inspector視圖,精靈面朝左
本文選自:Unity 2D遊戲開發快速入門大學霸內部資料,轉載請註明出處,尊重技術尊重IT人!