Zion插件分析——手柄(二)
发表于2016-10-31
在Zion插件中,提供了静态类来供外部调用手柄相关的接口,如ZionTrackedController和ZionController,直接调用它们的静态方法,就可以获取到我们需要的手柄数据,并且提供了主动获取和回调两种方式。
ZionTrackedController
简介
ZionTrackedController是一个MonoBehaviour类,在[CameraRig]下,左右手柄对象都绑定了该脚本。针对跟踪控制器,如Vive的手柄,Oculus Touch等。
使用方法
获取按键状态,以左手柄为例:
1 2 3 4 | if (ZionTrackedController.GetButtonDown(ZionController.Index.Left,ZionController.Button.Trigger)) { Debug.Log( "Trigger of left controller pressed" ); } |
1 2 | Vector2 currentTriggerAxis = new Vector2(); ZionTrackedController.GetAxis(ZionController.Index.Left, ZionController.Button.TriggerAxis, ref currentTriggerAxis); |
1 2 3 4 5 6 | void MyAxisHandler(ZionController.Index index, ZionController.Button button, Vector2 data) { Debug.Log(button + " on index " + index + " axis is : " + data); } // 传入None表示为左右两个手柄都绑定轴数据回调 ZionTrackedController.AddAxisDataHandler(ZionController.Index.None, MyAxisHandler) |
1 2 3 4 5 6 | void MyButtonDownHandler(ZionController.Index index, ZionController.Button button) { Debug.Log(button + " on index " + index + " press down" ); } //传入None表示为左右两个手柄都绑定按键回调 ZionTrackedController.AddTrackedButtonDownHandler(ZionController.Index.None, MyButtonDownHandler); |
1 2 3 4 | controllerVelocity = ZionTrackedController.GetVelocity(GetZionControllerIndex(controllerIndex)); controllerAngularVelocity = ZionTrackedController.GetAngularVelocity(GetZionControllerIndex(controllerIndex)); 震动手柄,以左手柄为例: ZionTrackedController.Vibrate(ZionController.Index.Left,500,500f,500f); |
分析
ZionTrackedController中各接口都依赖于ZionTrackedControllerBase实现。虽然左右手柄都绑定了ZionTrackedController,但是它中间有很多的静态成员和方法,即左右手柄共享的。
比如会保存全局的ZionTrackedController,left和right,其中有一个指向自己本身,谁左谁右根据索引index决定,ZionMonobehaviour中会根据[CameraRig]的设备管理器,来通知脚本(所有定义了SetDeviceIndex方法的脚本)设置正确的index。
1 | public static ZionTrackedController left, right; |
在这里的SetDeviceIndex中除了设置索引,就是要根据索引指定left和right分别对应谁,以及为自身对应的ZionTrackedControllerBase设置索引。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | private ZionTrackedControllerBase _controller; private ZionTrackedControllerBase controller { get {...} } } public void SetDeviceIndex( ulong index) { this .index = index; if index 为 1 lef = 自己; else if index 为 2 right = 自己; else controller.SetIndex(index); } |
主动获取按键状态
在获取按键状态时,需要传入参数ZionController.Index,传左得左,传右得右,如果传入None那么左右手柄任意一个,指定按键触发时都会返回true。
回调区分
在AddxxxHandler时,通过传入的索引来分别绑定事件到不同的回调接口
1 2 3 4 5 6 7 8 9 | case ZionController.Index.Left: lAxisDataHandler += handler; break ; case ZionController.Index.Right: rAxisDataHandler += handler; break ; case ZionController.Index.None: sAxisDataHandler += handler; break ; |
1 2 3 4 5 6 7 8 9 10 11 | if (index == Constants.indexLeft) { buttonDown = lButtonDownHandler; ... } else if (index == Constants.indexRight) { buttonDown = rButtonDownHandler; ... } controller.Notify(i, buttonDown, buttonUp, touchDown, touchUp, axisData); |
1 | controller.Notify(i, sButtonDownHandler, sButtonUpHandler, sTouchDownHandler, sTouchUpHandler, sAxisDataHandler); |
ZionController
Zion控制器,对外提供访问各种控制器(手柄)的接口,使用者可以只与本类打交道,提供主动获取系列接口和回调两种方式。
使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | if (ZionController.GetButtonDown(ZionController.Button.Enter)) { Debug.Log( "Enter pressed" ); } // 获取跟踪手柄的按键状态,以左手柄为例: if (ZionController.GetTrackedButtonDown(Constants.indexLeft, ZionController.Button.Trigger)) { Debug.Log( "Trigger of left controller pressed" ); } // 添加按键回调: void MyButtonDownHandler(ZionController.Button id) { Debug.Log( "button " + id + "pressed" ); } ZionController.AddButtonDownHandler(MyButtonDownHandler); 除此以外,全局的按键映射,事件委托定义也在ZionController中进行。 |
在ZionController中定义了控制器列表,用来存放所有可能的普通控制器,在构造方法中,根据ZionVR返回的平台类型,在列表中添加不同的普通控制器。
1 | private List new List |
在获取按键、轴数据状态,以及添加回调接口时,会先直接调用ZionTrackedController对应的静态接口,得到可追踪控制器的数据,然后遍历普通控制器列表,一一让它们获取。以获取按键按下为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 判断按键是否首次按下 public static bool GetButtonDown(Button id) { if (ZionTrackedController.GetButtonDown (Index.None, id)) { return true ; } foreach (ZionControllerBase controller in instance.controllers) { if (controller.GetButtonDown (id)) { return true ; } } return false ; } |