接触 Cocos Creator 已经一年多, 体验是酸甜苦辣俱全, 不过仍然要夸一下这东西确实神作, 可以让我这种网页小白靠着Unity开发经验直接上手. 到目前为止的 Cocos Creator 编辑器版本(v2.4.3), 对移动端的运动传感器支持仍然是有限, 只提供了一个加速度数据接口, 加速度数据可以提供重力方向, 动作力度, 轨迹识别, 算法好一点的还能粗略做个惯性导航. 但是, 可惜, 缺少了关键的陀螺仪传感器接口, 应用程序无法得知手机的3D姿态, 在某些应用中这是个必备的数据, 例如网页运行 VR游戏 和 Panorama(全景图片). 于是需要自己开发脚本组件实现.
根据以前开发 Android 原生VR应用的经验, 推测 Cocos Creator 不提供陀螺仪数据接口的原因, 可能是为了引擎稳定性和兼容性更好? 因为不是所有手机都有陀螺仪. 首先要搞清楚加速度传感器(Accelerometer)和陀螺仪传感器(Gyrometer)是两个独立的硬件设备, 有些低端手机是只有加速度传感器没有陀螺仪传感器(陀螺仪传感器更贵), 壕们可能很少见到这样的手机, 然而这种手机我就用过好几个. 奇葩的是这两个数据又是放在同一个HTML5事件传回的, 所以在自己开发的组件里, 首先要实现检测用户设备是否支持陀螺仪数据接口, 然后再实现功能和填各种坑.
加速度数据和陀螺仪数据在 HTML5 中统一由事件 DeviceMotionEvent 传回, 具体用法可以直接参考网上资料, DeviceMotionEvent - Web API 接口参考 | MDN (mozilla.org). 看了文档才知道, 事件传回数据中只包含了采样数据和时间戳, 如果设备没有陀螺仪传感器, 事件对象中的 "rotationRate" 是不存在的, JS代码中就是 "undefined", 通过检测 "rotationRate" 是否"undefined"可以判断陀螺仪设备是否存在.
如果是运行在 iPhone 手机上, 因为 iOS 系统对传感器权限的严格控制, DeviceMotionEvent 需要用户授权才能传出数据, 通过调试代码发现 iOS 系统里的 DeviceMotionEvent 有个 requestPermission 静态函数, 需要先调用一下这个静态函数, 弹出提示用户授权对话框, 用户选择允许后, 页面才能获得 DeviceMotion 事件和数据. Android 系统目前没有这种限制(估计以后也会有).
iPhone 上还有更严格的权限限制, requestPermission 必须在某个UI交互事件的回调函数中调用才能弹出请求授权对话框, 例如某个按钮的 OnClick, 如果在页面onload或场景初始化代码中悄无声息的 requestPermission 没有任何效果. Cocos Creator 程序可以在 Button 组件的 OnClick 事件处理代码中调用 requestPermission, 就可以在 iPhone 上成功弹出授权对话框. 解决授权问题扒了很多资料, 一直扒到了 DeviceOrientation Event Specification (w3c.github.io), 总算查清这个问题, 如果想看通俗易懂的总结可以看 在IOS中DeviceMotion及DeviceOrientation事件不触发的问题_greenwishing的专栏-CSDN博客.
其它小坑, 比如运行需要 HTTPS 协议, iPhone 手机上重力方向需要颠倒, iPhone 手机上传感器刷新时间的单位要转换等, 一一踩平...
搞清楚了以上问题和要点, 就可以自己实现一个运动传感器功能组件了, 展示的代码是被做成了名为 DeviceMotionEvent 的组件