Zion插件分析——Zion Monobehaviour
发表于2016-10-31
Zion插件中定义了虚基类ZionMonoBehaviour,用于每帧检测设备状态,实现事件分发。
但是它并不是一个真正的Monobehaviour,必须在真正的Monobehaviour实现类中,调用ZionMonoBehaviour实现类中重写的Update()等方法,来达到目的。ZionRender就是一个MonoBehaviour,在它的相关方法中,我们会去调用模拟的ZionMonobehaviour方法,来实现事件分发。
我们为SteamVR平台和Oculus平台实现了对应的ZionMonoBehaviour,但是作用不同。
一、ZionMonoBehaviourSteamVR.cs
SteamVR平台的ZionMonoBehaviour,只进行事件的分发。
Update()
获取底层OpenVR抛上来的事件,进行分发,同时转换为Zion的事件,也分发一次。对比原生的SteamVR_Render.Update(),有一处写法不同。
在SteamVR中,获取CVRSystem时,是这样做:
1 | var system = OpenVR.System; |
而我们的插件里,
1 | var system = SteamVR.instance.hmd; |
这是因为,如果OpenVR没有初始化,那么就有报空的隐患。而后面的做法,获取SteamVR单例时,会手动对其初始化
1 | OpenVR.Init( ref error); |
这样就可以确保在使用OpenVR.System时,它已经被初始化过了。
二、ZionMonoBehaviourOculusVR.cs
同样,Oculus平台下,它的主要功能也是进行分发事件,参考OVR插件中的OVRmanager.Update()。诸如焦点事件,模型隐藏事件等。
在类的开始,定义了几组字段,用于记录设备连接的相关参数,在事件分发时会用到。
Update()
上面的几组字段,“is”“has”开头的代表当前的设备状态,而“was”“had”“prev”开头的代表上一帧结束时设备的状态。当前的设备状态,每帧都会从OVRPlugin中取,取完以后与上一帧的设备状态进行对比,如果发现有变化,就通知ZionEvent发送相应事件。
以头盔连接为例,事件分发逻辑如下:
1 2 3 4 5 6 7 | // 分发头盔连接事件。 isHmdPresent = OVRPlugin.hmdPresent; if (wasHmdPresent != isHmdPresent) { Zion.ZionEvent.Send(Zion.ZionEvent.DEVICE_CONNECTED, Zion.Constants.indexHmd, isHmdPresent); } wasHmdPresent = isHmdPresent; |
从OVRPlugin中获取到头盔连接的状态isHmdPresent。
将当前头盔状态与旧的状态wasHmdPresent对比,如发生变化,就发送事件,通知大家设备当前的状态有更新。
最后,将最新的头盔状态保存到wasHmdPresent中去。
腾讯GAD游戏程序交流群:484290331