前几天Unity资源商城搞活动白嫖到了这个插件,但是看了下网上的教程都是比较旧的版本,所以决定学习记录一下。个人感觉比easy touch使用方便一些,而且easy touch很久没更新了。
运行插件内演示场景DemoScene。
按住shift键或者ctrl模拟双指操作,此时不需要点击鼠标左边,移动鼠标即可。如果点击就是三指操作。
shift+鼠标滚轮上下:模拟双指旋转
ctrl+鼠标滚轮上下:模拟双指缩放
打开FingersScriptPrefab,面板里的参数用于全局控制。
参数(后面用到特殊的会继续补充):
Default DPI:手势触发的灵敏度。如果值设置的特别大的话手势会延迟触发。除非有特殊需求不然用默认值即可。
首先声明手势Recognizer。
private TapGestureRecognizer tapGesture;
对Recognizer初始化并传入回调。
private void CreateTapGesture()
{
tapGesture = new TapGestureRecognizer();
tapGesture.StateUpdated += TapGestureCallback; //传入回调
FingersScript.Instance.AddGesture(tapGesture); //对应的有Remove
}
通过传入的回调触发行为。
private void DoubleTapGestureCallback(DigitalRubyShared.GestureRecognizer gesture)
{
if (gesture.State == GestureRecognizerState.Ended)
{
Debug.Log("Tap");
}
}
注意手势是全局的,不需要选中,如果想指定目标需要绑定目标或者自行加逻辑判断。
StateUpdated:注册手势的回调事件
tripleTapGesture.StateUpdated += PlatformSpecificViewTapUpdated;
PlatformSpecificView:指定点击的目标
tripleTapGesture.PlatformSpecificView = bottomLabel.gameObject;
NumberOfTapsRequired:Tap手势的连点次数。单击、双击等都是靠这个区分
tripleTapGesture.NumberOfTapsRequired = 3;
AddGesture:注册手势
FingersScript.Instance.AddGesture(tripleTapGesture);
GestureRecognizerState:手势回调中判断当前的执行阶段
if (gesture.State == GestureRecognizerState.Ended)
RequireGestureRecognizerToFail:添加或移除一个需要失败的手势。 设置为 null 可以清除所有需要失败的手势。比如说下面的例子意思为如果doubleTapGesture手势触发了就会导致tapGesture触发失败。其实就是防止手势冲突使用的
tapGesture.RequireGestureRecognizerToFail = doubleTapGesture;
gesture.FocusX, gesture.FocusY:回调中点击的屏幕坐标
DebugText("Double tapped at {0}, {1}", gesture.FocusX, gesture.FocusY);
Direction:设置滑动方向
swipeGesture.Direction = SwipeGestureRecognizerDirection.Down;
DirectionThreshold:对于设置的方向,这是在该方向与另一个方向上必须成比例的滑动量。 例如,与沿 x 轴移动相比,向下滑动手势需要在 y 轴上移动更多倍数。 默认值为 1.5,这意味着向下滑动手势需要在 y 轴与 x 轴上大 1.5 倍。小于或等于 1 表示任何比率都可以接受。简单来说就是这个值越大就需要越贴合目标方向
swipeGesture.DirectionThreshold = directionThreshold;
// allow a swipe, regardless of slope
gesture.StartFocusX, gesture.StartFocusY:手势开始的位置
DebugText("Swiped from {0},{1} to {2},{3}; velocity: {4}, {5}", gesture.StartFocusX, gesture.StartFocusY, gesture.FocusX, gesture.FocusY, swipeGesture.VelocityX, swipeGesture.VelocityY);
swipeGesture.VelocityX, swipeGesture.VelocityY:滑动的速度(根据focus)
DebugText("Swiped from {0},{1} to {2},{3}; velocity: {4}, {5}", gesture.StartFocusX, gesture.StartFocusY, gesture.FocusX, gesture.FocusY, swipeGesture.VelocityX, swipeGesture.VelocityY);
MinimumNumberOfTouchesToTrack:设置最少用到的手指数,一般用1或2。要注意不是每个手势都支持多指
panGesture.MinimumNumberOfTouchesToTrack = 2;
MaximumNumberOfTouchesToTrack:设置最大用到的手指数,默认用1或2
longPressGesture.MaximumNumberOfTouchesToTrack = 1;
gesture.DeltaX, gesture.DeltaY:手势位移的距离
DebugText("Panned, Location: {0}, {1}, Delta: {2}, {3}", gesture.FocusX, gesture.FocusY, gesture.DeltaX, gesture.DeltaY);
scaleGesture.ScaleMultiplier:手指距离的缩放值
DebugText("Scaled: {0}, Focus: {1}, {2}", scaleGesture.ScaleMultiplier, scaleGesture.FocusX, scaleGesture.FocusY);
rotateGesture.RotationRadiansDelta:旋转弧度的变化
Earth.transform.Rotate(0.0f, 0.0f, rotateGesture.RotationRadiansDelta * Mathf.Rad2Deg);
AllowSimultaneousExecution:允许多个手势同时操作一个目标
panGesture.AllowSimultaneousExecution(scaleGesture);
panGesture.AllowSimultaneousExecution(rotateGesture);
scaleGesture.AllowSimultaneousExecution(rotateGesture);
CaptureGestureHandler:捕获点击的目标并处理。返回false是可穿透,true为不可穿透,null为默认。
FingersScript.Instance.CaptureGestureHandler = CaptureGestureHandler;
private static bool? CaptureGestureHandler(GameObject obj)
{
if (obj.name.StartsWith("PassThrough"))
{
return false;
}
else if (obj.name.StartsWith("NoPass"))
{
return true;
}
return null;
}
ComponentTypesToDenyPassThrough(重点注意):除了gesture view之外设置可阻挡gesture检测的类型。比如防止穿透UI。
FingersScript.Instance.ComponentTypesToDenyPassThrough.Add(typeof(UnityEngine.UI.Image));
StartOrResetGesture:开始或重置手势。参数分别为手势、目标是否显示在最前面(只对sprite有效)、相机、执行手势的游戏对象、显示的sprite、执行手势的模式(是在绑定物体上执行还是任意对象)、接收的相机
FingersScript.StartOrResetGesture(r, BringToFront, Cameras, gameObject, spriteRenderer, GestureRecognizerComponentScriptBase.GestureObjectMode.RequireIntersectWithGameObject, out camera);
ClearTrackedTouchesOnEndOrFail:是否在手势结束或失败时清空跟踪的touches,默认为false。 一般情况下设置为false
tapGesture.ClearTrackedTouchesOnEndOrFail = true;
AddMask:为手势添加限制区域。参数为collider和手势。只有在Mask范围内点击目标才会生效
FingersScript.Instance.AddMask(Mask1, tapGesture);
AllowSimultaneousExecutionWithAllGestures:允许和其他所有手势一起执行
tapGesture2.AllowSimultaneousExecutionWithAllGestures();
FingersScript.HasInstance:检测场景中是否有FingersScript实例
if (FingersScript.HasInstance)
ShowTouches:显示模拟的点击,仅在调试时执行此操作,因为它会干扰其他Canvas
FingersScript.Instance.ShowTouches = true;
获取点击位置所有可接收射线的物体。
private void TapGestureUpdated(DigitalRubyShared.GestureRecognizer gesture)
{
if (gesture.State == GestureRecognizerState.Ended)
{
Debug.Log("Tapped on " + gesture.PlatformSpecificView);
List<UnityEngine.EventSystems.RaycastResult> results = new List<UnityEngine.EventSystems.RaycastResult>();
UnityEngine.EventSystems.PointerEventData eventData = new UnityEngine.EventSystems.PointerEventData(UnityEngine.EventSystems.EventSystem.current);
eventData.position = new Vector2(gesture.FocusX, gesture.FocusY);
UnityEngine.EventSystems.EventSystem.current.RaycastAll(eventData, results);
Debug.Log("Event system raycast count: " + results.Count + ", objects: " + string.Join(",", results.Select(r => r.gameObject.name).ToArray()));
}
}
参数比较简单,直译或者查看代码即可理解。
DeadZone:死区,小于该值的不会触发摇杆效果。类似敏感度
InputCurve:传值曲线
EightAxisMode:八角模式,摇杆会变成上下左右和对角八个方向,摇杆转动有间隔感
MaxRangeRadiusMultiplier:摇杆中心圆拖动到边界时的偏移
FollowSpeed:摇杆整体跟随手指的速度,默认为0
StartMode:MustStartInside(摇杆静止,在摇杆上操作)MoveToPanStart(根据Pan手势作为摇杆起始点)PanInsideOrPanMovesInside(摇杆静止,在Pan手势区域内操作)
RestrictJoystickPositionTo:需要Unity2019以上。将摇杆位置限制在此 collider2D 上,null 表示没有限制。将 colider 放在摇杆父对象中
ReturnToHomePosition:操作完后自动回到初始位置
Cross Platform Input:输入轴
Callbacks:摇杆回调,接收Vector2
使用方法
为摇杆传入回调事件。当然也可以在面板上绑定。
Joystick.JoystickExecuted = JoystickExecuted;
为摇杆加入遮罩。(可选)
FingersScript.Instance.AddMask(Mask1, JoystickScript.PanGesture);
查看DemoSceneComponents场景。面板上功能与前面API介绍的差不多。
场景:DemoScene3DOrbit
效果:可以方便的实现对目标物体的旋转移动和缩放,通过调整参数快速的实现想要的效果。
长按拖拽物体,3D或sprite、UI都可以,但注意只有sprite有显示在最前面的效果,可以自己修改逻辑。
作者做了很多案例,都是使用这款插件的核心功能扩展的,这里就不一一记述了,大家可以自行翻阅以加深理解。
后续用到其他知识点会继续补充。
遇到问题,FingersScript与我的游戏框架中生成的UICanvas冲突了,Canvas接收不到点击事件。
解决方案: 在场景中创建一个UI->EventSystem,不要动态生成。