腳本 "輸入控制" 函式記錄


Unity 在輸入控制方面提供相當多的方法,不同的平台有不同的功能,如桌上型裝置(PC,MAC)有滑鼠,鍵盤控制,移動裝置(Android ,Ios)有觸碰,虛擬搖桿控制,為了能確認控制的功能,我們先在場景中利用 Plane 和 Cube 建立盒子並在盒子中間建立一顆球(Sphere)改名為 Ball ,並加入這篇提到的物理效果,輸入控制都歸類在 Input 類別中,你可以到 Unity Script Reference 輸入 Input 查看,接著開始來測試 "輸入控制" 的功能吧,建立腳本並附屬在 Main Camera 上,腳本內容為

   1:  var ballObj : GameObject;
   2:   
   3:  function Start()
   4:  {
   5:      ballObj = GameObject.Find("Ball");
   6:  }
   7:   
   8:  function FixedUpdate () 
   9:  {
  10:      detectGetAxis();
  11:  }
  12:   
  13:  function detectGetAxis()
  14:  {
  15:       var tempconV = Input.GetAxis ("Vertical");
  16:       
  17:       var tempconH = Input.GetAxis ("Horizontal");
  18:       
  19:       print("tempconV:"+tempconV);
  20:       
  21:       print("tempconH:"+tempconH);
  22:       
  23:       ballObj.rigidbody.AddForce(tempconH*20,0,tempconV*20);
  24:  }

第 1 ~ 11 行和此篇範例類似,只不過尋找的物件名改為 Ball
第 13 ~ 24 行為測試方法,第 15 和 17 行 Input.GetAxis () 為取得軸向方法, 其中 "Vertical" 為垂直軸,而 "Horizontal" 為水平軸,至於垂直和水平軸的定義為何呢? 你可以自己查看, 步驟為

Edit -> Project Settings -> Input 

Inspector 視窗會出現 Axes ,點擊後出現一堆軸向名稱,再點開 Vertical 或 Horizontal 就能看到軸向定義,從定義中可以看到 Vertical 的正向為 W 鍵和 方向鍵上 反向為 S 鍵和方向鍵下,OK~ 我們回到 Input.GetAxis () 方法會回傳 -1 ~ 1 的數值,當你按著正向鍵時,數值會從 0 遞增到 1,相對的按著反向鍵,數值會從 0 遞減到 -1 , 不按正向和反向鍵數值就會回到 0 , 第 19 和 21 行可以觀察這2個數值,第 23 行 ballObj.rigidbody.AddForce(tempconH*20,0,tempconV*20) 簡單的說就是將 ballObject 加入移動的向量,其中 AddForce(tempconH*20,0,tempconV*20) 就是加入的 X,Y,Z 軸向量,這種作法可以簡單的移動物件,接著介紹如何取得鍵盤上的任一按鍵,方法如下

   1:  function detectGetKey()
   2:  {
   3:      
   4:      var tempbutton = Input.GetKey(KeyCode.A);
   5:      
   6:      if(tempbutton)
   7:      {
   8:          print("tempbutton:"+tempbutton);
   9:      } 
  10:           
  11:  }

第 4 行的 KeyCode.A 代表鍵盤上的 A 鍵,所有鍵盤上的按鍵都歸類在 KeyCode 中,可參考這篇 , Input.GetKey(KeyCode.A) 就是如果按了鍵盤上的 A 鍵 ,會回傳 true ,測試時可能覺得奇怪為何按一次 A 鍵, Console 視窗出現多次 print 原因是 Unity 預設 Input.GetKey() 方法為連發作用,所以會造成多次反應,如果只是想單次觸發的話,使用以下方法就能取得單次觸發動作

   1:  Input.GetKeyDown(KeyCode.A);

接著介紹滑鼠按鈕的取得,滑鼠按鈕可分為左鍵,中鍵,右鍵,取得方法如下

   1:  function detectGetMouseButton()
   2:  {
   3:      //mouse left button
   4:      var tempmousebutton = Input.GetMouseButton(0);
   5:      
   6:      if(tempmousebutton)
   7:      {
   8:          print("tempmousebutton:"+tempmousebutton);
   9:      } 
  10:      
  11:  }

在 Input.GetMouseButton(0) 中, 0 代表取得滑鼠左鍵狀態,按下的話回傳 true , 1 代表右鍵, 2 代表中間鍵,想取得單次的滑鼠按鍵動作使用

   1:  Input.GetMouseButtonDown(0);

接下來是加速度器的控制,目前一般的智慧型手機多有嵌入相關的硬體, Unity 有提供簡單的方法讓我們可以方便使用,如下

   1:  function detectAcceleration()
   2:  {
   3:      var tempx = Input.acceleration.x;
   4:      var tempy = Input.acceleration.y;
   5:      var tempz = Input.acceleration.z;
   6:      
   7:      ballObj.rigidbody.AddForce(-tempy*30,0,tempx*30);
   8:      
   9:  }

第 3 行 Input.acceleration.x 就是取得加速度器的 X 軸向量,第 4 ~ 5 行也是相同的意思
第 7 行再把這些數值給予球體,以觀察球體的移動

Unity 也提供虛擬搖桿 (Joysticks) 和觸碰版 (Touchpad) 的控制, 我們先在場景中放入虛擬搖桿,步驟為

Project 視窗的 Standard Assets (Mobile)資料夾 -> Prefabs 資料夾 -> 將 Dual JoySticks 拖曳到 Scene 視窗

Scene 視窗會出現 2 個虛擬搖桿物件,  Hierarchy 視窗可以看到左邊名稱的為 LeftJoystick , 右邊為 RightJoystick ,接著我們在腳本中修改部分程式碼以取得虛擬搖桿物件,如下

   1:  var ballObj : GameObject;
   2:   
   3:  var tempLjoystick : Joystick; 
   4:  var tempRjoystick : Joystick; 
   5:   
   6:  function Start()
   7:  {
   8:      ballObj = GameObject.Find("Ball");
   9:      
  10:      tempLjoystick = GameObject.Find("LeftJoystick").GetComponent(Joystick);
  11:      tempRjoystick = GameObject.Find("RightJoystick").GetComponent(Joystick);
  12:  }

第 3 ~ 4 行宣告 Joystick 物件
第 10 ~ 11 行尋找名稱為 LeftJoystick 和 RightJoystick 的物件,那麼要如何取得虛擬搖桿的數值變化呢?? 使用以下方法

   1:  function detectJoyStick()
   2:  {
   3:      ballObj.rigidbody.AddForce(tempLjoystick.position.x*10,0,tempLjoystick.position.y*10);
   4:  }

其中 tempLjoystick.position.x 就是取得搖桿的 X 軸變化,當我們不控制搖桿時, X 和 Y 軸都是 0,壓住搖桿拖曳時,X ,Y 軸就會出現數值的變化,再取其變化做動作如第 3 行所示,這邊只示範左邊的搖桿控制,想要控制右邊搖桿使用同樣方法就可以了

最後介紹觸碰的控制,移動裝置(Android,IOS等等)上最主要的控制就是觸碰功能, Unity 將觸碰點歸類成 Touch 結構(參考官網說明),我們需要做的就是取得 Touch 結構中的 position 屬性來判斷觸碰點的座標再作後續動作,如下


   1:  function detectTouch(a:int)
   2:  {
   3:      //case 0
   4:      if(a==0)
   5:      {
   6:          if(Input.touchCount>0)
   7:          {
   8:              var touch1 = Input.GetTouch(0);
   9:          
  10:              if(touch1.position.x < Screen.width/2 && touch1.position.y < Screen.height/2)
  11:              {
  12:                  ballObj.rigidbody.AddForce(-20,0,-20);
  13:              }
  14:              else if(touch1.position.x < Screen.width/2 && touch1.position.y > Screen.height/2)
  15:              {
  16:                  ballObj.rigidbody.AddForce(-20,0,20);
  17:              }
  18:              else if(touch1.position.x > Screen.width/2 && touch1.position.y < Screen.height/2)
  19:              {
  20:                  ballObj.rigidbody.AddForce(20,0,-20);
  21:              }
  22:              else if(touch1.position.x > Screen.width/2 && touch1.position.y > Screen.height/2)
  23:              {
  24:                  ballObj.rigidbody.AddForce(20,0,20);
  25:              }
  26:          }
  27:      
  28:      }
  29:      //case 1
  30:      else if(a==1)
  31:      {
  32:          var temptouchs  = Input.touches;
  33:          
  34:          if(temptouchs.Length>0)
  35:          {        
  36:              if(temptouchs[0].position.x < Screen.width/2 && temptouchs[0].position.y < Screen.height/2)
  37:              {
  38:                  ballObj.rigidbody.AddForce(-20,0,-20);
  39:              }
  40:              else if(temptouchs[0].position.x < Screen.width/2 && temptouchs[0].position.y > Screen.height/2)
  41:              {
  42:                  ballObj.rigidbody.AddForce(-20,0,20);
  43:              }
  44:              else if(temptouchs[0].position.x > Screen.width/2 && temptouchs[0].position.y < Screen.height/2)
  45:              {
  46:                  ballObj.rigidbody.AddForce(20,0,-20);
  47:              }
  48:              else if(temptouchs[0].position.x > Screen.width/2 && temptouchs[0].position.y > Screen.height/2)
  49:              {
  50:                  ballObj.rigidbody.AddForce(20,0,20);
  51:              }
  52:          }        
  53:      
  54:      }    
  55:      
  56:  }

 function detectTouch(a:int) 提供 2 種方法取得觸碰點,我們從第 4 行(第 1 種方法)開始看起,首先第 6 行 Input.touchCount 取得觸碰點總數,總數大於 0 才需要做下面的判斷
第 8 行 Input.GetTouch(0) 中 , 0 代表第 1 個觸碰點(Touch) ,之後的觸碰點以此類推
第 10 行 touch1.position.x 就是取得第 1 個觸碰點的 X 座標, touch1.position.y 則是觸碰點的 Y 座標, Screen.width 就是螢幕畫面寬度(800), Screen.height 為螢幕畫面高度(480),我把螢幕畫面分為 4 個部分,如下圖











所以 if(touch1.position.x < Screen.width/2 && touch1.position.y < Screen.height/2) 意思就是當觸碰點位於 "左下" 的區域,就對球體施加移動的力量,第 14, 18, 22 行分別對應左上,右下,右上區域,第 2 方法(第 30 行),其中 32 行 Input.touches 會回傳 Touch 結構的陣列
第 118 行判斷陣列總數是否大於0
第 121 行 temptouchs[0] 就是取得 Touch 結構的陣列的第 1 個元素(第 1 個觸碰點),等同 Input.GetTouch(0) 後面就類似於第 1 個方法

注意: Touch 類別中還有一項屬性可以使用就是 Phase (階段或層次),參考官網說明 ,使用 Phase 可以更詳細的分辨觸碰動作,如當我們只想觸碰螢幕 1 次,觸發 1 次動作,就可加入

   1:  function detectTouch()
   2:  {
   3:      if(Input.touchCount>0)
   4:      {
   5:          var touch1 = Input.GetTouch(0);
   6:          
   7:          if(touch1.phase==TouchPhase.Began)
   8:          {
   9:              //action
  10:          }
  11:      }
  12:  }

其中第 7 行判斷當 touch1 的 phase 為 Began 時才 action , 代表這個 action 只在觸碰的開頭動作 1 次

整段程式碼如下

   1:  //#pragma strict
   2:   
   3:  //Ball
   4:  var ballObj : GameObject;
   5:   
   6:  //Joystick use
   7:  var tempLjoystick : Joystick; 
   8:  var tempRjoystick : Joystick; 
   9:   
  10:  function Start()
  11:  {
  12:      ballObj = GameObject.Find("Ball");
  13:      
  14:      tempLjoystick = GameObject.Find("LeftJoystick").GetComponent(Joystick);
  15:      tempRjoystick = GameObject.Find("RightJoystick").GetComponent(Joystick);
  16:   
  17:  }
  18:   
  19:  function Update () 
  20:  {
  21:      detectTouch(0);
  22:  }
  23:   
  24:  //Get Axis
  25:  function detectGetAxis()
  26:  {
  27:       var tempconV = Input.GetAxis ("Vertical");
  28:       
  29:       var tempconH = Input.GetAxis ("Horizontal");
  30:       
  31:       print("tempconV:"+tempconV);
  32:       
  33:       print("tempconH:"+tempconH);
  34:       
  35:       ballObj.rigidbody.AddForce(tempconH*20,0,tempconV*20);
  36:  }
  37:   
  38:  //Get KeyBoard
  39:  function detectGetKey()
  40:  {
  41:      
  42:      var tempbutton = Input.GetKeyDown(KeyCode.A);
  43:      
  44:      if(tempbutton)
  45:      {
  46:          print("tempbutton:"+tempbutton);
  47:      } 
  48:           
  49:  }
  50:   
  51:  //Get MouseButton
  52:  function detectGetMouseButton()
  53:  {
  54:      //mouse left button
  55:      var tempmousebutton = Input.GetMouseButtonDown(0);
  56:      
  57:      if(tempmousebutton)
  58:      {
  59:          print("tempmousebutton:"+tempmousebutton);
  60:      } 
  61:      
  62:  }
  63:   
  64:  function detectAcceleration()
  65:  {
  66:      var tempx = Input.acceleration.x;
  67:      var tempy = Input.acceleration.y;
  68:      var tempz = Input.acceleration.z;
  69:      
  70:      ballObj.rigidbody.AddForce(-tempy*30,0,tempx*30);
  71:      
  72:  }
  73:   
  74:  function detectJoyStick()
  75:  {
  76:      ballObj.rigidbody.AddForce(tempLjoystick.position.x*10,0,tempLjoystick.position.y*10);
  77:  }
  78:   
  79:  function detectTouch(a:int)
  80:  {
  81:   
  82:      //case 0
  83:      if(a==0)
  84:      {
  85:          if(Input.touchCount>0)
  86:          {
  87:              var touch1 = Input.GetTouch(0);
  88:              
  89:              if(touch1.position.x < Screen.width/2 && touch1.position.y < Screen.height/2)
  90:              {
  91:                  ballObj.rigidbody.AddForce(-20,0,-20);
  92:              }
  93:              else if(touch1.position.x < Screen.width/2 && touch1.position.y > Screen.height/2)
  94:              {
  95:                  ballObj.rigidbody.AddForce(-20,0,20);
  96:              }
  97:              else if(touch1.position.x > Screen.width/2 && touch1.position.y < Screen.height/2)
  98:              {
  99:                  ballObj.rigidbody.AddForce(20,0,-20);
 100:              }
 101:              else if(touch1.position.x > Screen.width/2 && touch1.position.y > Screen.height/2)
 102:              {
 103:                  ballObj.rigidbody.AddForce(20,0,20);
 104:              }
 105:          }
 106:      
 107:      }
 108:      //case 1
 109:      else if(a==1)
 110:      {
 111:          var temptouchs  = Input.touches;
 112:          
 113:          if(temptouchs.Length>0)
 114:          {        
 115:          
 116:              if(temptouchs[0].position.x < Screen.width/2 && temptouchs[0].position.y < Screen.height/2)
 117:              {
 118:                  ballObj.rigidbody.AddForce(-20,0,-20);
 119:              }
 120:              else if(temptouchs[0].position.x < Screen.width/2 && temptouchs[0].position.y > Screen.height/2)
 121:              {
 122:                  ballObj.rigidbody.AddForce(-20,0,20);
 123:              }
 124:              else if(temptouchs[0].position.x > Screen.width/2 && temptouchs[0].position.y < Screen.height/2)
 125:              {
 126:                  ballObj.rigidbody.AddForce(20,0,-20);
 127:              }
 128:              else if(temptouchs[0].position.x > Screen.width/2 && temptouchs[0].position.y > Screen.height/2)
 129:              {
 130:                  ballObj.rigidbody.AddForce(20,0,20);
 131:              }
 132:          }        
 133:      
 134:      }    
 135:      
 136:  }












以上就是輸入控制的介紹和記錄~~

標籤: