昨天搬家,我被无情的从4楼请上了10楼。原因就是房东们为了争家产打官司,受伤的永远是我们这些打工的租房的码农,呵呵!结果就是我们两家做了一个调换把房子换了一下。东西太多了,真的好累啊,好累啊~~前几天有个朋友问我Unity手势操作,后来我还帮他做了一个例子。我觉得在Unity中用这个手势操作的插件会很方便。以前我只是知道FingerGestures,但是没有深入的用过,这两天学习了一下。真的很好用。
最近研究了一下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 139 140 |
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 12 13 |
// 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祝大家学习愉快,啦啦啦。
- 本文固定链接: https://www.xuanyusong.com/archives/1869
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
网上找了很久 都是讲解的作用,看了momo您的介绍,知道应该怎么做了,先谢谢了
momo,加速度怎么算?
关注你很久了,我想请教一个问题,现在的效果是//滑动中 080 void OnFingerDragMove( int fingerIndex, Vector2 fingerPos, Vector2 delta ) 081 { 082 transform.position = GetWorldPos( fingerPos ); 083 Debug.Log(” OnFingerDragMove =” fingerPos); 084 085 } 也就是不管我点击那里,transform都会直接跑过去,我想实现打飞机那种那种如何实现?还有就是他的边界处理?
关注你很久了,我想请教一个问题,现在的效果是//滑动中 080 void OnFingerDragMove( int fingerIndex, Vector2 fingerPos, Vector2 delta ) 081 { 082 transform.position = GetWorldPos( fingerPos ); 083 Debug.Log(” OnFingerDragMove =” +fingerPos); 084 085 } 也就是不管我点击那里,transform都会直接跑过去,我想实现打飞机那种那种如何实现?还有就是他的边界处理?
现在,新版本的,貌似不能这么用了!
你好,这个插件是不是在android手机上按下home键退出再进来以后,原本的第一根手指就变成第二根了。再同样操作一次之后变成第三根了。按下home键的时候是不是有问题
顶起
求回复啊~~
MOMO哥,请问一下我用它内置的TBDrag Orbit脚本的时候,我是在win7触控屏上测试的,旋转查看、缩放效果都没问题,但是两个手指平移的时候就不好用,请问有没有什么方法解决呢?灰常感谢~~(我之前在安卓上测试是好用的)
屏幕是红外触控屏~
您好 请问这个生成的文件也可以导入eclipse和我的主程序一起编么?我如果要是想做3D的互动,用手势控制植物本身旋转,做一个展示的效果,可以用这个么?
不可以 unity不能做出来一个view 只能把你的东西加在它里面。。
您好 请问这个生成的文件也可以导入eclipse和我的主程序一起编么?我如果要是想做3D的互动,用手势控制植物本身旋转,做一个战士的效果,可以用这个么?
插件怎么定义鼠标中键按住是拖动呢 费解很久了
插件怎么定义鼠标中键按住是拖动呢 费解很久了
没太明白global gestures和finger gestures的区别,大神麻烦简单解释下
谢谢分享,但是项目文件导不进去,报错提示:Error while importing package: Couldn’t decompress packageFailed importing package
是不是中文路径 mac下中文路径不会抱错
windows下需要用英文的。
你好。想请教一个问题。想实现点击一个按钮可以保存当前场景,场景中有一些动态加载上的模型都保存,把当前的场景保存成一个新的场景。这应该怎么实现呢?求指导。
用数据来驱动吧,把保存的东西存在二进制文件中。。 打开场景的时候去读取二进制文件,然后根据条件来加载吧。。
您的意思是存好某个地方,放了什么物体。什么属性都用类似于xml存储起来。然后重新加载场景时,在动态读取,然后动态加载上就可以是吗?
不变的东西 就不用存在本地, 可变的东西存在本地 包括 位置 旋转 缩放 组件 即可
插件挺好用的。
momo大神,顶起,学习了
一起吧。。
我也来顶起!
蛤蛤 用手势操作把。。。
自己沙发!!!
查件怎么定义鼠标中键按住是拖动呢 费解很久了
查件怎么定义鼠标中键按住是拖动呢 费解很久了