今天來寫一寫Unity3D中兩個比較常用插件:EasyTouch和NGUI的學習心得。我用的版本分別是EasyTouch 3.1.1和NGUI 3.6.0,下面也是對這兩個版本的學習心得。
1. EasyTouch
EasyTouch是為觸摸屏准備的插件,提供了觸摸屏的虛擬按鍵,大致包括3部分:搖桿、按鈕和觸摸響應。
1.1 EasyTouch搖桿
這個搖桿就是通過手指在搖桿區域的滑動控制你想控制的物體上下左右移動的,當手指觸摸到搖桿上面進行移動時,可以通過MovingJoystick類的變量獲取移動靈敏度。當然,使用教程網上也有很多,這里不詳細講了,只是簡單進行主要流程說明。在使用時,首先要添加一個事件相應函數:EasyJoystick.On_JoystickMove += OnJoystickMove; 其中OnJoystickMove是函數名,需要自己實現這個函數,這個函數的原型需要是: void OnJoystickMove(MovingJoystick move) ,其中接收一個MovingJoystick的變量,可以通過move.joystickAxis.x和move.joystickAxis.y獲取左右和前后的移動距離,這里的x對應Unity3D中的x軸(左右移動方向),y對象Unity3D中的z軸(前進后退方向),這樣就可以控制物體移動了。通過搖桿控制物體當然還有其他方法,可以不寫代碼,直接將需要控制移動的物體通過Inspector面板賦值給它也可以,我沒有用過,這里就不講了。
1.2 EasyTouch按鈕
EasyTouch也貼心的提供了按鈕,可以通過下圖的操作直接創建一個按鈕,並指定相應事件,和按鈕的Texture。
EasyTouch提供了Normal Texture和Active Texture兩個接口,分別是平時的按鈕紋理和按鈕被按下時的紋理。
EasyTouch按鈕添加事件也很方便,在Inspector面板中找到Receiver Object,這里把你要接受消息的對象拖過來,然后在Down method name里面寫上函數名(不要加括號),這樣當你按下按鈕時,它就會去在你指定的接收對象的腳本中去尋找這個函數,然后執行。
但是EasyTouch按鈕有個缺點就是按鈕的外觀是通過Texture指定的,如果你想在上面添加文字,或者想在游戲中變換其上面的文字只能通過重新加載新的紋理實現,加載新紋理可以使用Resource.Load函數。可以使用如下代碼,注意Resource.Load中的第一個參數是紋理名稱,紋理放在Assets下的Resources目錄下面這個函數就可以找到。按鈕上面加文字可以使用OnGUI,NGUI或者自己PS一個按鈕的Texture,在里面加上文字。
EasyButtonName.ActiveTexture = Resources.Load("ActiveTexturePath", typeof(Texture2D)) as Texture2D;
1.3 EasyTouch
EasyTouch最主要的功能還是提供了手指在屏幕上的觸摸行為,包括按下、雙擊、長按、拖拽等。我用到了滑動,也就是手指在屏幕上滑動控制攝像機的旋轉。
觸發滑動操作的相應函數需要添加EasyTouch.On_SwipeStart、EasyTouch.On_Swipe和EasyTouch.On_SwipeEnd方法,分別表示滑動開始、滑動中、滑動結束的方法,當然如果不需要滑動開始和結束,也可以不添加。這些方法的原型是 void OnSwipe(Gesture gesture) ,滑動的多少可以通過gesture.deltaPosition.x和gesture.deltaPosition.x獲取。
最后還要說一下,在這個版本的EasyTouch中有一個bug:當你一只手使用搖桿,另一只手在屏幕滑來滑去控制攝像機視角時,會引發這個bug。該bug在手機上的表現就是:當你放開控制搖桿的手時,發現搖桿並沒有復位,而是卡在搖桿區域的邊緣,控制的對象還在運動。在電腦端這個問題比較難重現,是因為電腦端用鼠標點,只有一個鼠標,一般不會觸發這個bug,因此這個bug在手機上發生時就表現的很詭異,不知道是什么原因。在電腦端重現的方法:用鼠標移動搖桿,此時鼠標按住不要動,然后按下ctrl鍵(如下圖可以設置),屏幕會出現一個黃色的圓點,然后仍然按住鼠標不動,移動鼠標,會發現Unity3D的Console窗口有紅字提示錯誤:NullReferenceException: Object reference not set to an instance of an object。
通過搜索,找到了解決方法,在這個網站上http://forum.unity3d.com/threads/released-easy-touch.135192/page-13#post-1400790有人提出了這個問題,在下面EasyTouch制作團隊進行了回復,說這是一個bug,並給出了臨時解決方案,在Easytouch腳本中做如下修改:
Replace line 1193 :
1 gesture.isHoverReservedArea = IsTouchReservedArea( fingers[twoFinger0].fingerIndex) || IsTouchReservedArea( fingers[twoFinger1].fingerIndex);
by
1 if (fingers[twoFinger0] != null){ 2 gesture.isHoverReservedArea = IsTouchReservedArea( fingers[twoFinger0].fingerIndex); 3 } 4 if (fingers[twoFinger1] != null){ 5 gesture.isHoverReservedArea = gesture.isHoverReservedArea || IsTouchReservedArea( fingers[twoFinger1].fingerIndex); 6 }
And replace line 1181 1182:
1 gesture.pickCamera = fingers[twoFinger0].pickedCamera; 2 gesture.isGuiCamera = fingers[twoFinger0].isGuiCamera;
by
1 if (fingers[twoFinger0] != null){ 2 gesture.pickCamera = fingers[twoFinger0].pickedCamera; 3 gesture.isGuiCamera = fingers[twoFinger0].isGuiCamera; 4 } 5 else if (fingers[twoFinger1] != null){ 6 gesture.pickCamera = fingers[twoFinger1].pickedCamera; 7 gesture.isGuiCamera = fingers[twoFinger1].isGuiCamera; 8 }
大家也可以點擊上面的網址,直接去看他的回復。EasyTouch就先寫到這里,下面簡單寫一下NGUI的使用心得。
2. NGUI
NGUI是制作UI用的,為什么不用Unity3D自帶的OnGUI呢?網上說OnGUI會在一幀內調用好多次,導致效率非常低,尤其是到移動平台更是明顯,自己也沒做過很復雜的UI,對這點感受還不深,但是為了適應移動平台,還是學了NGUI。
對於新版NGUI來說,整個界面、操作以及使用方法變化較大,很多網上的教程已經跟不上版本的變化了,這里只能自己慢慢摸索,現在學的也不是很深,大概說一下制作NGUI按鈕的一個流程吧。
創建一個NGUI界面,首先可以通過下圖所示按鈕創建一個2D或3D界面。
點擊2D UI或者3D UI后,在Hierarchy中會出現UI Root或者UI Root(3D),這里以2D為例吧,3D比較復雜。在UI Root里面自帶了一個Camera是用來顯示UI的,我們可以通過設置這個Camera的Culling Mask控制它只顯示我們給UI Root以及下面的子對象指定的Layer,然后讓Main Camera不顯示這些Layer,這樣可以防止在游戲中可能會看到多個UI的情況。然后呢,在UI Root下面新建一個Panel,把一組按鈕放在這個Panel上面,方便統一管理,如果不想新建Panel也可以。接着創建一個Sprite,在這個對象上添加NGUI自帶的Button腳本(用於設置響應,顯示為UIButton)和Box Collider(用於響應點擊),設置按鈕的響應函數的一個方法是在這里拖入一個對象,拖入一個對象后,在Notify下面會顯示Meshod,可以再這里選擇在該對象的腳本中定義好的一個public方法作為單擊相應函數,注意一定是public方法,否則Method里面找不到。
關於按鈕上的文字,可以通過創建一個Label實現,這樣一個按鈕就創建好了。當然,按鈕還可以有各種動畫,這些可以參考NGUI自帶的Example,里面做了很多例子。
還有關於錨點的,老版本的NGUI需要將按鈕什么的對象放到一個Anchor下面,在新版本中不用了,在很多NGUI的腳本中都已經集成了Anchors,就像下面這樣,可以通過這種方式去設置位置。
今天就寫這么多吧,關於NGUI也還學的不深,寫的比較簡單。本文如果有不正確的地方,歡迎指正。