最近看SteamVR 和VR TK 发现SteamVr中有一个很好的按钮事件脚本
脚本路径 SteamVR/Extras/Steamvr_TrackedController.cs
将这个脚本改造成一个基类 来实现左右手柄监听功能的
这是其中一种按钮事件
var system = OpenVR.System; if (system != null && system.GetControllerState(controllerIndex, ref controllerState)) {
//trigger 代表的是按钮按下的程度 0L 表示松开 bool 值在判断只有按钮按下后才会触发松开 保证松开不会一直触发 ulong trigger = controllerState.ulButtonPressed & (1UL << ((int)EVRButtonId.k_EButton_SteamVR_Trigger)); if (trigger > 0L && !triggerPressed) { triggerPressed = true; ClickedEventArgs e; e.controllerIndex = controllerIndex; e.flags = (uint)controllerState.ulButtonPressed; e.padX = controllerState.rAxis0.x; e.padY = controllerState.rAxis0.y; OnTriggerClicked(e); } else if (trigger == 0L && triggerPressed) { triggerPressed = false; ClickedEventArgs e; e.controllerIndex = controllerIndex; e.flags = (uint)controllerState.ulButtonPressed; e.padX = controllerState.rAxis0.x; e.padY = controllerState.rAxis0.y; OnTriggerUnclicked(e); }
通过以上脚本可以做到 按钮按下的轻重情况 也可以做到按钮按两次 或者三次 再触发的事件。使用更新次数索引值 来触发或者bool都可以的。
然后写一个子类继承用来做控制器,以后每一个手柄公用的功能都写在这里,根据依赖倒置原则,来最后分配左右手不同的功能。
这里增加一个抓取功能 ,参考的时候官方的SteamVR_TestThrow
public class VRControlller : SteamVR_TrackedController {
//可抓取物体 public GameObject holdObj; //抓取点 public Rigidbody attachPoint; //关节 FixedJoint joint; //手柄组件 SteamVR_TrackedObject trackedObj; protected virtual void Start() { trackedObj = this.transform.GetComponent<SteamVR_TrackedObject>(); attachPoint = this.transform.GetChild(0).GetComponent<Rigidbody>(); MenuButtonClicked += VRControlller_MenuButtonClicked; MenuButtonUnclicked += VRControlller_MenuButtonUnclicked; TriggerClicked += VRControlller_TriggerClicked; TriggerUnclicked += VRControlller_TriggerUnclicked; SteamClicked += VRControlller_SteamClicked; PadClicked += VRControlller_PadClicked; PadUnclicked += VRControlller_PadUnclicked; PadTouched += VRControlller_PadTouched; PadUntouched += VRControlller_PadUntouched; Gripped += VRControlller_Gripped; Ungripped += VRControlller_Ungripped; }
{
.........事件功能
}
#region 抓取功能 //抓 protected virtual void TakeObj(GameObject obj) { if (!joint) { obj.transform.position = attachPoint.transform.position; joint = obj.AddComponent<FixedJoint>(); joint.connectedBody = attachPoint; } } //扔 protected virtual void ThrowObj(GameObject obj) { var device = SteamVR_Controller.Input((int)trackedObj.index); if (joint) { var go = joint.gameObject; var rigidbody = go.GetComponent<Rigidbody>(); Object.DestroyImmediate(joint); joint = null; Object.Destroy(go, 15.0f); var origin = trackedObj.origin ? trackedObj.origin : trackedObj.transform.parent; if (origin != null) { rigidbody.velocity = origin.TransformVector(device.velocity); rigidbody.angularVelocity = origin.TransformVector(device.angularVelocity); } else { rigidbody.velocity = device.velocity; rigidbody.angularVelocity = device.angularVelocity; } rigidbody.maxAngularVelocity = rigidbody.angularVelocity.magnitude; } } #endregion
//使用的关节绑定 写成子物体也可以 不过速度要跟随手柄
然后子类 右手 左手 根据不同的情况重写父类监听的方法即可
class VRControllerRight : VRControlller { protected override void Start() { base.Start(); } protected override void Update() { base.Update(); }
protected override void 监听方法名字(){
base.监听方法名字();
}
这样简易的可拓展,可控制的手柄交互结构就搞定了。震动功能可以直接添加到父类上
2017.3.10 lc
