最近研究了一下Unity中的一个手势操作的插件FingerGestures。它能很方便监听到Unity中的各种手势事件:上下左右四方向的滑动事件、按下事件、抬起事件、移动事件、连击事件、长按事件等等。它同时支持触摸屏操作与鼠标操作,总起来说使用起来还是比较方便的,今天写下教程记录这个插件的详细使用步骤。首先下载这个插件,大家可以在圣典上找这个插件的下载地址,当然也可以在本文最后下载该插件。
我看了一下这个插件底层的实现步骤,他是通过C#代理的形式来实现手势操作的。如下图红圈内所示,这五个重要的预设用来监听触摸与鼠标的手势事件。包括:单手触摸事件、双手触摸事件、鼠标事件、触摸事件。这里我们使用一个单手的事件,如图中所示将Finger Gertures Initializer拖拽入左侧层次视图中。
OK,上面我们说了该插件是通过C#代理形式来接收事件消息的,所以我们需要用脚本来注册这些事件从而开始接收消息。接着创建一个立方体对象用以处理手势操作,当然你也可以处理游戏中的任何对象。编写脚本FingerEvent.cs ,把这个脚本挂在这个立方体对象之上。
FingerEvent.cs脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
using UnityEngine; using System.Collections; public class FingerEvent : MonoBehaviour { void OnEnable() { //启动时调用,这里开始注册手势操作的事件。 //按下事件: OnFingerDown就是按下事件监听的方法,这个名子可以由你来自定义。方法只能在本类中监听。下面所有的事件都一样!!! FingerGestures.OnFingerDown += OnFingerDown; //抬起事件 FingerGestures.OnFingerUp += OnFingerUp; //开始拖动事件 FingerGestures.OnFingerDragBegin += OnFingerDragBegin; //拖动中事件... FingerGestures.OnFingerDragMove += OnFingerDragMove; //拖动结束事件 FingerGestures.OnFingerDragEnd += OnFingerDragEnd; //上、下、左、右、四个方向的手势滑动 FingerGestures.OnFingerSwipe += OnFingerSwipe; //连击事件 连续点击事件 FingerGestures.OnFingerTap += OnFingerTap; //手指触摸屏幕中事件调用一下三个方法 FingerGestures.OnFingerStationaryBegin += OnFingerStationaryBegin; FingerGestures.OnFingerStationary += OnFingerStationary; FingerGestures.OnFingerStationaryEnd += OnFingerStationaryEnd; //长按事件 FingerGestures.OnFingerLongPress += OnFingerLongPress; } void OnDisable() { //关闭时调用,这里销毁手势操作的事件 //和上面一样 FingerGestures.OnFingerDown -= OnFingerDown; FingerGestures.OnFingerUp -= OnFingerUp; FingerGestures.OnFingerDragBegin -= OnFingerDragBegin; FingerGestures.OnFingerDragMove -= OnFingerDragMove; FingerGestures.OnFingerDragEnd -= OnFingerDragEnd; FingerGestures.OnFingerSwipe -= OnFingerSwipe; FingerGestures.OnFingerTap -= OnFingerTap; FingerGestures.OnFingerStationaryBegin -= OnFingerStationaryBegin; FingerGestures.OnFingerStationary -= OnFingerStationary; FingerGestures.OnFingerStationaryEnd -= OnFingerStationaryEnd; FingerGestures.OnFingerLongPress -= OnFingerLongPress; } //按下时调用 void OnFingerDown( int fingerIndex, Vector2 fingerPos ) { //int fingerIndex 是手指的ID 第一按下的手指就是 0 第二个按下的手指就是1。。。一次类推。 //Vector2 fingerPos 手指按下屏幕中的2D坐标 //将2D坐标转换成3D坐标 transform.position = GetWorldPos( fingerPos ); Debug.Log(" OnFingerDown =" +fingerPos); } //抬起时调用 void OnFingerUp( int fingerIndex, Vector2 fingerPos, float timeHeldDown ) { Debug.Log(" OnFingerUp =" +fingerPos); } //开始滑动 void OnFingerDragBegin( int fingerIndex, Vector2 fingerPos, Vector2 startPos ) { Debug.Log("OnFingerDragBegin fingerIndex =" + fingerIndex + " fingerPos ="+fingerPos +"startPos =" +startPos); } //滑动结束 void OnFingerDragEnd( int fingerIndex, Vector2 fingerPos ) { Debug.Log("OnFingerDragEnd fingerIndex =" + fingerIndex + " fingerPos ="+fingerPos); } //滑动中 void OnFingerDragMove( int fingerIndex, Vector2 fingerPos, Vector2 delta ) { transform.position = GetWorldPos( fingerPos ); Debug.Log(" OnFingerDragMove =" +fingerPos); } //上下左右四方方向滑动手势操作 void OnFingerSwipe( int fingerIndex, Vector2 startPos, FingerGestures.SwipeDirection direction, float velocity ) { //结果是 Up Down Left Right 四个方向 Debug.Log("OnFingerSwipe " + direction + " with finger " + fingerIndex); } //连续按下事件, tapCount就是当前连续按下几次 void OnFingerTap( int fingerIndex, Vector2 fingerPos, int tapCount ) { Debug.Log("OnFingerTap " + tapCount + " times with finger " + fingerIndex); } //按下事件开始后调用,包括 开始 结束 持续中状态只到下次事件开始! //OnFingerStationary 事件和 OnFingerDragMove 有一个区别。 //OnFingerStationary 是手指触摸在屏幕中的事件,而OnFingerDragMove是先触摸一下然后滑动的事件。 //如果你需要时时捕获手指触摸屏幕中的事件时 用OnFingerStationary 即可 void OnFingerStationaryBegin( int fingerIndex, Vector2 fingerPos ) { Debug.Log("OnFingerStationaryBegin " + fingerPos + " times with finger " + fingerIndex); } void OnFingerStationary( int fingerIndex, Vector2 fingerPos, float elapsedTime ) { Debug.Log("OnFingerStationary " + fingerPos + " times with finger " + fingerIndex); } void OnFingerStationaryEnd( int fingerIndex, Vector2 fingerPos, float elapsedTime ) { Debug.Log("OnFingerStationaryEnd " + fingerPos + " times with finger " + fingerIndex); } //长按事件 void OnFingerLongPress( int fingerIndex, Vector2 fingerPos ) { Debug.Log("OnFingerLongPress " + fingerPos ); } //把Unity屏幕坐标换算成3D坐标 Vector3 GetWorldPos( Vector2 screenPos ) { Camera mainCamera = Camera.main; return mainCamera.ScreenToWorldPoint( new Vector3( screenPos.x, screenPos.y, Mathf.Abs( transform.position.z - mainCamera.transform.position.z ) ) ); } } |
如下图所示,用鼠标还是IOS Android触摸事件都能很好的在这个Cube上响应,大家把我的代码手动的打一遍就什么都明白了。
上面的脚本,我们是直接绑定在立方体对象上来监听它,如果你想在别的脚本监听这个立方体对象的手势操作。只需调用如下方法即可。这个方法官方封装在了SampleBase中。因为官方的例子程序脚本是继承它的,所以子类就可以直接使用父类的方法。可是SampleBase会自动初始化一个SampleUI的脚本,不想初始化这个脚本的话直接用下面方法就行,原理就是通过射线我就不过多的解释了。传递鼠标或触摸的2D坐标即可得到触摸的3D模型对象。
1 2 3 4 5 6 7 8 9 10 11 |
// Return the GameObject at the given screen position, or null if no valid object was found public static GameObject PickObject( Vector2 screenPos ) { Ray ray = Camera.main.ScreenPointToRay( screenPos ); RaycastHit hit; if( Physics.Raycast( ray, out hit ) ) return hit.collider.gameObject; return null; } |
最后大家仔细看一下官方的FingerGestures.cs脚本,所有的手势操作的事件都在这里,包括单手操作事件、双手操作事件、鼠标操作事件。
插件以及源码下载地址:http://vdisk.weibo.com/s/ifRgG
雨松MOMO祝大家学习愉快,啦啦啦。
- 本文固定链接: http://www.xuanyusong.com/archives/1869
- 转载请注明: 雨松MOMO 2012年11月17日 于 雨松MOMO程序研究院 发表