今天来写一写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也还学的不深,写的比较简单。本文如果有不正确的地方,欢迎指正。