Zion插件分析——手柄(二)

发表于2016-10-31
评论0 2.5k浏览
  在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;
  然后在Update()中,根据当前脚本的索引来决定Notify传入哪个回调接口:
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);
  然后,无论索引为何,都通知sXXXHandler接口:
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 controllers = 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;
}

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引