[C#]使用Dictionary時的注意事項

1.要先加入


 using System.Collections.Generic;  



2.之後再宣告就可以使用嚕。
使用前記得要把變數new出來就是了。


 //宣告 
 protected Dictionary<int, csBehaviorBase> m_dicObjBehaviors; 
 //建立 
 m_dicObjBehaviors = new Dictionary<int, csBehaviorBase>();  

[Unity]設定遊戲手把與取得輸入

參考資料:Input
                    Input Manager

測試手把 :PS Analog gamepad
Script語言:C#
Unity 版本:3.4

Unity提供了3種輸入裝置可以使用,鍵盤、滑鼠、以及遊戲手把。
此篇紀錄在取得遊戲手把輸入時,所遇到的問題以及解決方案。

首先,要先開啟Unity提供的Input Manager(Edit->Project Setting->Input Manager),就可以看到Unity所提供預設的按鈕事件。這邊也可以自訂自己想要用的按鈕,只需要更改size欄位的數值即可,Unity就會利用最後一組按鈕做為參考值,複製一份新的按鈕設定。官方稱這些設定為虛擬軸(Virtual Axes)或是虛擬按鈕(Virtual Button)。


Unity提供預設兩組水平輸入以及垂直輸入,一組是提供給鍵盤訊息使用,另一組是設定給遊戲手把使用。不過這兩個輸入是使用相同的名稱。這邊推測,是要讓寫script的時候,不需要根據裝置而另外寫輸入判斷或是數值取得。如果是這樣設計的話,那算是還蠻方便的功能。


為了測試Unity是否能正確接收到遊戲手把的訊息,就寫了底下的測試程式來測試結果。
 using UnityEngine;  
 using System.Collections;  
   
 public class InputTest : MonoBehaviour {  
     protected float m_JoyX = 0.0f;  
     protected float m_JoyY = 0.0f;  
       
     // Use this for initialization  
     void Start () {  
       
     }  
       
     // Update is called once per frame  
     void Update ()   
     {          
         m_JoyX = Input.GetAxis("Horizontal");  
         m_JoyY = Input.GetAxis("Vertical");  
                 
         Debug.Log("Get Horizontal input from Joystick = " + m_JoyX.ToString());  
         Debug.Log("GetVertical input from Joystick = " + m_JoyY.ToString());  
     }  
 }  
   

測試結果:

測試結果還不錯,用手把或是鍵盤都可以接收到訊息。


不過這種作法有個缺點,就是Update()是每個frame都會更新一次,所以就會一直收到沒按下按鍵時的資料。
因此需要做一些判斷式來確定按鍵有按下時,才取得所需要的按鍵值。
所以更改後的程式碼如下:
   
 using UnityEngine;  
 using System.Collections;  
   
 public class InputTest : MonoBehaviour {  
     protected float m_JoyX = 0.0f;  
     protected float m_JoyY = 0.0f;  
       
     // Use this for initialization  
     void Start () {  
       
     }  
       
     // Update is called once per frame  
     void Update ()   
     {          
         m_JoyX = Input.GetAxis("Horizontal");  
         m_JoyY = Input.GetAxis("Vertical");  
           
         if( Input.GetButton("Horizontal") )  
         {  
             Debug.Log("Get Horizontal input from Joystick = " + m_JoyX.ToString());  
         }else if(Input.GetButton("Vertical")) {  
             Debug.Log("GetVertical input from Joystick = " + m_JoyY.ToString());  
         }  
           
         if( Input.GetKey(KeyCode.JoystickButton11) ){  
             print("Get Joystick Button 0");  
         }  
           
         //Debug.Log("Get Horizontal input from Joystick = " + m_JoyX.ToString());  
     }  
 }  
   

測試結果如下圖:

結果,手把訊息沒進來?!
之後試過很多方法,例如把按鍵名稱改成不同的名稱,也是一樣沒有接收到手把方向鍵按下的訊息。
這邊的測試就繞了很久,後來索性把手把方向鍵是否有輸入這件事情,改成判定軸向值是否有值(也就是不為0)。結果就可正常的在手把方向鍵按下時,才取得所要的數值。

原本不曉得是不是Unity的bug還是限制,畢竟這一塊的說明,官方文件沒有講得很清楚。而提供的按鍵訊息也只有上、下、左、右四個鍵盤按鍵而已。目前推測是,因為手把輸入的Type為Joystick Axis,然後軸並沒有所謂的按鈕觀念,所以這邊就無法用Input.GetButton()來取得是否有按下這個動作。


改判定軸向是否有值後,的確解決上述的問題,但與鍵盤要同時共用的時候,卻又出了問題
就是因為手把跟鍵盤是使用相同的虛擬按鈕名稱,所以取得的軸向資料有時並不是手把輸入的,反而會是鍵盤輸入的。


因此目前為了解決這問題,就是把手把輸入跟鍵盤輸入的虛擬按鈕名稱改成不一樣,這樣就可以確定輸入的資料是確切的來自於鍵盤還是手把。雖然在實作遊戲的時候會很不方便(因為要另外把手把輸入拆出來判斷),但是如果透過繼承跟多型,是可以讓實作遊戲變方便。至於如何繼承跟多型的部分就之後另外開個主題紀錄了(因為目前還在測試中XD)。

最後可以同時使用鍵盤與遊戲手把輸入,但也不會互相影響的方式如下:
或是在Input Manager內使用相同的熱鍵名稱也行。之前測試不過可能是有設定沒弄好。 2011/08/31
 using UnityEngine;  
 using System.Collections;  
   
 public class InputTest : MonoBehaviour {  
     protected float m_JoyX = 0.0f;  
     protected float m_JoyY = 0.0f;  
       
     // Use this for initialization  
     void Start () {  
       
     }  
       
     // Update is called once per frame  
     void Update ()   
     {  
         m_JoyX = Input.GetAxis("Horizontal_Joy");  
         m_JoyY = Input.GetAxis("Vertical_Joy");  
           
         if( Input.GetButton("Horizontal") )  
         {  
             print("Get Horizontal input from keyboard = " + Input.GetAxis("Horizontal").ToString());  
         }else if( Input.GetButton("Vertical") ){  
             print("Get Vertical input from keyboard = " + Input.GetAxis("Vertical").ToString());  
         }else if( Input.GetButton("Horizontal_Joy") ){//m_JoyX != 0.0f ){  
             Debug.Log("GetHorizontal input from Joystick = " + m_JoyX.ToString());  
         }else if( m_JoyY != 0.0f ){  
             Debug.Log("GetVertical input from Joystick = " + m_JoyY.ToString());  
         }  
           
         if( Input.GetKey(KeyCode.JoystickButton11) ){  
             print("Get Joystick Button 0");  
         }  
     }  
 }  

測試結果如下:

輸出結果也就很符合目前的需求嚕。

不過此時Joystick Y軸上為負值,所以有需要用Y軸上為正值時,需把Inverse選項打勾,就可以了。


PS.1.官方有註明鍵盤跟手把的軸向值介於-1到1。滑鼠部分則不一定在此區間。
PS.2.在測試過程中發現,把Dead設為0.00001以下時,在手把方向鍵未按下時,Input.GetAxis()取得到的座標值其實是不為零的。
         因此如果使用別的手把時,發現官方的預設值無法讓未按下方向鍵時取得的值為零的情況下,只要把Dead參數改大就好。反之如果按下按鍵後,收到的值為零,就把Dead參數改小(大於0,小於1)就可以了。
         官方對於Dead的說明為,當收到的按鍵數值低於Dead的值的時候,就會強制設為0。

Build docker image from multiple build contexts

Build docker image from multiple build contexts ...