unity零基礎開始學習做游戲(二)讓你的對象動起來


 

-------小基原創,轉載請給我一個面子

  小基認為電子游戲與電影最重要的區別就是交互,如果電子游戲沒有讓你輸入的交互功能的話,全程都“只可遠觀,而不可鼓搗”的話,你可能是在看視頻,怕不是玩了假游戲。所以小基來講講如何輸入並控制物體移動

首先雙擊unity

 點擊NEW,給你的工程(游戲)起個有意思的名字(突發發現小基隨便起的這個Test1856有《教團1886》的既視感XD

創建之后就是一個空場景,右上角的布局小基習慣用2by3這種風格,你可以自行選擇。

點擊create,里面可以創建各種基本的物體(2d,3d等)這里隨便創建一個3d的cube

之后在Project下,選中Assets,點擊create創建一個C#Script腳本,起名叫做MyInput好了

下面上代碼

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 
  5 public class MyInput : MonoBehaviour {
  6     //移動方向枚舉(這里列舉8方向的移動,注釋里面的數字是用小鍵盤數字的物理位置指代方向,格斗游戲術語)
  7     enum MoveDir
  8     {
  9         None,   //不動
 10         Up,     //上8
 11         Down,   //下2
 12         Left,   //左4
 13         Right,  //右6
 14         UL,     //左上7
 15         UR,     //右上9
 16         DL,     //左下1
 17         DR,     //右下3
 18     }
 19 
 20     //輸入按鍵常量(之后走配置)
 21     const KeyCode INPUT_UP = KeyCode.W;
 22     const KeyCode INPUT_DOWN = KeyCode.S;
 23     const KeyCode INPUT_LEFT = KeyCode.A;
 24     const KeyCode INPUT_RIGHT = KeyCode.D;
 25 
 26     //默認移動方向
 27     private MoveDir moveDir = MoveDir.None;
 28     //按壓記錄
 29     private bool isUpPress = false;
 30     private bool isDownPress = false;
 31     private bool isLeftPress = false;
 32     private bool isRightPress = false;
 33 
 34     //是否可以移動
 35     private bool canMove = true;
 36     //右移動
 37     private Vector3 MOVE_RIGHT = new Vector3(1, 0, 0);
 38     //上移動
 39     private Vector3 MOVE_UP = new Vector3(0, 1, 0);
 40 
 41     //外部調控速度(為了方便看效果)
 42     public float speed = 2f;
 43     //移動速度向量
 44     private Vector3 move_speed_dir = Vector3.zero;
 45     //移動距離
 46     private Vector3 move_dis = Vector3.zero;
 47 
 48     //控制目標
 49     public Transform target;
 50 
 51     // Use this for initialization
 52     void Start () {
 53         
 54     }
 55     
 56     // Update is called once per frame
 57     void Update () {
 58         CheckInputKey();
 59         CheckMoveDir();
 60     }
 61 
 62     void FixedUpdate()
 63     {
 64         CheckMove();
 65     }
 66 
 67     //檢測輸入按鍵
 68     void CheckInputKey()
 69     {
 70         //檢測單一輸入
 71         foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
 72         {
 73             if (Input.GetKeyDown(kcode))
 74             {
 75                 Debug.Log("Single KeyCode: " + kcode);
 76                 ChangeKeyPressState(kcode, true);
 77             }
 78 
 79             if (Input.GetKeyUp(kcode))
 80             {
 81                 Debug.Log("Single KeyCode: " + kcode);
 82                 ChangeKeyPressState(kcode, false);
 83             }
 84         }
 85     }
 86 
 87     //記錄按鍵的按壓狀態
 88     void ChangeKeyPressState(KeyCode keyCode, bool isPress)
 89     {
 90         switch(keyCode)
 91         {
 92             case INPUT_UP:
 93                 isUpPress = isPress;
 94                 break;
 95             case INPUT_DOWN:
 96                 isDownPress = isPress;
 97                 break;
 98             case INPUT_LEFT:
 99                 isLeftPress = isPress;
100                 break;
101             case INPUT_RIGHT:
102                 isRightPress = isPress;
103                 break;
104         }
105     }
106 
107     //確定移動方向
108     void CheckMoveDir()
109     {
110         //確定方向
111         if(isUpPress && isLeftPress)
112         {
113             moveDir = MoveDir.UL;
114         }
115         else if(isUpPress && isRightPress)
116         {
117             moveDir = MoveDir.UR;
118         }
119         else if (isDownPress && isLeftPress)
120         {
121             moveDir = MoveDir.DL;
122         }
123         else if (isDownPress && isRightPress)
124         {
125             moveDir = MoveDir.DR;
126         }
127         else if(isUpPress)
128         {
129             moveDir = MoveDir.Up;
130         }
131         else if (isDownPress)
132         {
133             moveDir = MoveDir.Down;
134         }
135         else if (isLeftPress)
136         {
137             moveDir = MoveDir.Left;
138         }
139         else if (isRightPress)
140         {
141             moveDir = MoveDir.Right;
142         }
143         else
144         {
145             moveDir = MoveDir.None;
146         }
147     }
148 
149     //檢測是否可以移動
150     void CheckMove()
151     {
152         //某些情況下可能禁止移動,例如暫停,播放CG等
153         if(canMove && moveDir != MoveDir.None)
154         {
155             PlayerMove(target, speed);
156         }
157     }
158 
159     //移動
160     void PlayerMove(Transform target, float speed)
161     {
162         move_dis = speed * Time.deltaTime * GetSpeedDir();
163         target.position += move_dis;
164     }
165 
166     //速度向量
167     Vector3 GetSpeedDir()
168     {
169         switch(moveDir)
170         {
171             case MoveDir.Up:
172                 move_speed_dir = MOVE_UP;
173                 break;
174             case MoveDir.Down:
175                 move_speed_dir = -MOVE_UP;
176                 break;
177             case MoveDir.Left:
178                 move_speed_dir = -MOVE_RIGHT;
179                 break;
180             case MoveDir.Right:
181                 move_speed_dir = MOVE_RIGHT;
182                 break;
183             case MoveDir.UL:
184                 move_speed_dir = MOVE_UP - MOVE_RIGHT;
185                 break;
186             case MoveDir.UR:
187                 move_speed_dir = MOVE_UP + MOVE_RIGHT;
188                 break;
189             case MoveDir.DL:
190                 move_speed_dir = -MOVE_UP - MOVE_RIGHT;
191                 break;
192             case MoveDir.DR:
193                 move_speed_dir = -MOVE_UP + MOVE_RIGHT;
194                 break;
195         }
196         return move_speed_dir.normalized;
197     }
198 }

!!!!網上有很多講輸入控制如何移動,但是多數都是講單一按下,對於同時按下2個或2個以上按鍵並沒有說明怎么解決,這里小基研究了一下方便大家!!!!!

(如果你直接寫input.GetKey去讀輸入,直接執行物體移動的話,判斷格個方向時邏輯時,如果使用if-elseif這種的話,多按鍵輸入時候,必定只能執行其中一個方向。
如果用if判斷各個方向,那么當“上”方向和“右”方向同時按下時,物理軌跡是“右上”方向,而你單個方向速度如果都是v的話,合速度方向為√2,相當於斜着走速度會變快,這兩個方式都不能接受)
update()里面每幀檢測CheckInputKey(),是否有按鍵按下或者抬起,ChangeKeyPressState()這個方法里面記下來當前有哪些按鍵輸入。
CheckMoveDir()這個方法就是專門為了根據按下的按鍵的值來判斷,合方向是枚舉中的哪一種(這個有另一種思路,后面單獨說)
CheckMove(),PlayerMove()這兩個方法就是檢測當前能不能移動,能移動的話就移動

target.position += move_dis;這個代碼意思是把target這個物體的位置移動到新位置,a += b就相當於a = a + b,理解為在原來位置基礎上再偏移move_dis就好
GetSpeedDir()這個方法里面就是根據方向枚舉,確定移動的方向向量,確定完合方向后,記得要用.normalized取單位長度,這樣就能保證斜方向速度與正交方向速度相同。
 
接下來把MyInput腳本拖到cube上,Target也綁定cube,設置好speed,點擊三角開始按鈕(變為藍色表示運行)
試試單一按鍵,兩個按鍵一起按下,都能正常移動

--------------------------------------另一種思路解決多按鍵同時按下控制移動----------------------------------------------------
上面那種方法,判斷按下按鍵轉換方向時,只處理了一個按鍵按下,和兩個按鍵同時按下,那么如果我同時按下三個按鍵或者四個按鍵時候就會出問題
下面上代碼,區別看下面解釋
  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 
  5 public class MyInput2 : MonoBehaviour {
  6     //移動方向枚舉
  7     enum MoveDir
  8     {
  9         None = 0,       //不動
 10         Up = 1,         //上8
 11         Down = -1,      //下2
 12         Left = 10,      //左4
 13         Right = -10,    //右6
 14         UL = 11,        //左上7
 15         UR = -9,        //右上9
 16         DL = 9,         //左下1
 17         DR = -11,       //右下3
 18     }
 19 
 20     //輸入按鍵常量(之后走配置)
 21     const KeyCode INPUT_UP = KeyCode.W;
 22     const KeyCode INPUT_DOWN = KeyCode.S;
 23     const KeyCode INPUT_LEFT = KeyCode.A;
 24     const KeyCode INPUT_RIGHT = KeyCode.D;
 25 
 26     //默認移動方向
 27     private MoveDir moveDir = MoveDir.None;
 28     //按壓值
 29     private int moveDirValue = 0;
 30     //按壓記錄
 31     private bool isUpPress = false;
 32     private bool isDownPress = false;
 33     private bool isLeftPress = false;
 34     private bool isRightPress = false;
 35 
 36     //是否可以移動
 37     private bool canMove = true;
 38     //右移動
 39     private Vector3 MOVE_RIGHT = new Vector3(1, 0, 0);
 40     //上移動
 41     private Vector3 MOVE_UP = new Vector3(0, 1, 0);
 42 
 43     //外部調控速度
 44     public float speed = 2f;
 45     //移動速度向量
 46     private Vector3 move_speed_dir = Vector3.zero;
 47     //移動距離
 48     private Vector3 move_dis = Vector3.zero;
 49 
 50     //控制目標
 51     public Transform target;
 52 
 53     // Use this for initialization
 54     void Start () {
 55         
 56     }
 57     
 58     // Update is called once per frame
 59     void Update () {
 60         CheckInputKey();
 61         CheckMoveDir();
 62     }
 63 
 64     void FixedUpdate()
 65     {
 66         CheckMove();
 67     }
 68 
 69     //檢測輸入按鍵
 70     void CheckInputKey()
 71     {
 72         //檢測單一輸入
 73         foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
 74         {
 75             if (Input.GetKeyDown(kcode))
 76             {
 77                 Debug.Log("Single KeyCode: " + kcode);
 78                 ChangeKeyPressState(kcode, true);
 79             }
 80 
 81             if (Input.GetKeyUp(kcode))
 82             {
 83                 Debug.Log("Single KeyCode: " + kcode);
 84                 ChangeKeyPressState(kcode, false);
 85             }
 86         }
 87     }
 88 
 89     //記錄按鍵的按壓狀態
 90     void ChangeKeyPressState(KeyCode keyCode, bool isPress)
 91     {
 92         switch(keyCode)
 93         {
 94             case INPUT_UP:
 95                 isUpPress = isPress;
 96                 break;
 97             case INPUT_DOWN:
 98                 isDownPress = isPress;
 99                 break;
100             case INPUT_LEFT:
101                 isLeftPress = isPress;
102                 break;
103             case INPUT_RIGHT:
104                 isRightPress = isPress;
105                 break;
106         }
107     }
108 
109     //確定移動方向
110     void CheckMoveDir()
111     {
112         moveDirValue = 0;
113         //確定方向
114         if(isUpPress)
115         {
116             moveDirValue += (int)MoveDir.Up;
117         }
118         if (isDownPress)
119         {
120             moveDirValue += (int)MoveDir.Down;
121         }
122         if (isLeftPress)
123         {
124             moveDirValue += (int)MoveDir.Left;
125         }
126         if (isRightPress)
127         {
128             moveDirValue += (int)MoveDir.Right;
129         }
130     }
131 
132     //檢測是否可以移動
133     void CheckMove()
134     {
135         //某些情況下可能禁止移動,例如暫停,播放CG等
136         if(canMove && moveDirValue != (int)MoveDir.None)
137         {
138             PlayerMove(target, speed);
139         }
140     }
141 
142     //移動
143     void PlayerMove(Transform target, float speed)
144     {
145         move_dis = speed * Time.deltaTime * GetSpeedDir();
146         target.position += move_dis;
147     }
148 
149     //速度向量
150     Vector3 GetSpeedDir()
151     {
152         switch(moveDirValue)
153         {
154             case (int)MoveDir.Up:
155                 move_speed_dir = MOVE_UP;
156                 break;
157             case (int)MoveDir.Down:
158                 move_speed_dir = -MOVE_UP;
159                 break;
160             case (int)MoveDir.Left:
161                 move_speed_dir = -MOVE_RIGHT;
162                 break;
163             case (int)MoveDir.Right:
164                 move_speed_dir = MOVE_RIGHT;
165                 break;
166             case (int)MoveDir.UL:
167                 move_speed_dir = MOVE_UP - MOVE_RIGHT;
168                 break;
169             case (int)MoveDir.UR:
170                 move_speed_dir = MOVE_UP + MOVE_RIGHT;
171                 break;
172             case (int)MoveDir.DL:
173                 move_speed_dir = -MOVE_UP - MOVE_RIGHT;
174                 break;
175             case (int)MoveDir.DR:
176                 move_speed_dir = -MOVE_UP + MOVE_RIGHT;
177                 break;
178         }
179         return move_speed_dir.normalized;
180     }
181 }

 

 

 

枚舉方向定義了不同的值,這樣同時按下三個按鍵的時候,必定有兩個方向時一對相反的,那么求“合”速度時候,就可以抵消掉。如果四個方向同時按下,就相當於不動了,問題搞定!

沒有經驗的同學按照這個流程一步一步做,應該也能實現移動物體這個效果的。

順便祝願你們都有三次元會動的“對象”(來自單身狗的真誠祝福)

 

工程下載https://pan.baidu.com/s/1opWziUOW7QdzMpn3hcaQ4A

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM