/// <summary> /// Permanently sets the range of motion for this component. /// </summary> /// <param name="newRangeOfMotion"> /// The new range of motion to be set. /// WithController being the best estimation of where fingers are wrapped around the controller (pressing buttons, etc). /// WithoutController being a range between a flat hand and a fist.</param> /// <param name="blendOverSeconds">How long you want the blend to the new range of motion to take (in seconds)</param> public void SetRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f) { if (rangeOfMotion != newRangeOfMotion) { RangeOfMotionBlend(newRangeOfMotion, blendOverSeconds); } }
public void SetSkeletonRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f) { if (handSkeleton != null) { handSkeleton.SetRangeOfMotion(newRangeOfMotion, blendOverSeconds); } }
public void SetSkeletonRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f) { for (int i = 0; i < renderModels.Count; i++) { renderModels[i].SetSkeletonRangeOfMotion(newRangeOfMotion, blendOverSeconds); } }
private void UpdateHandJoints(uint deviceIndex, ulong actionHandle, bool isLeft) { if (deviceIndex == INVALID_DEVICE_INDEX || actionHandle == OpenVR.k_ulInvalidActionHandle) { return; } IVRModuleDeviceState prevState; IVRModuleDeviceStateRW currState; if (TryGetValidDeviceState(deviceIndex, out prevState, out currState)) { RigidPose fixedHandPose = currState.pose; fixedHandPose.rot *= SteamVR_Action_Skeleton.steamVRFixUpRotation; EVRSkeletalMotionRange skeletonType = (EVRSkeletalMotionRange)(isLeft ? VIUSettings.steamVRLeftSkeletonMode : VIUSettings.steamVRRightSkeletonMode); EVRInputError boneError = OpenVR.Input.GetSkeletalBoneData(actionHandle, EVRSkeletalTransformSpace.Model, skeletonType, s_tempBoneTransforms); if (boneError == EVRInputError.None) { AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.Wrist, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.wrist); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.ThumbMetacarpal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.thumbMetacarpal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.ThumbProximal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.thumbProximal); //AssignHandJoint(handPose, isLeft, currState.handJoints, HandJointName.ThumbIntermediate, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.thumbMiddle); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.ThumbDistal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.thumbDistal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.ThumbTip, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.thumbTip); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.IndexMetacarpal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.indexMetacarpal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.IndexProximal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.indexProximal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.IndexIntermediate, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.indexMiddle); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.IndexDistal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.indexDistal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.IndexTip, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.indexTip); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.MiddleMetacarpal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.middleMetacarpal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.MiddleProximal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.middleProximal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.MiddleIntermediate, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.middleMiddle); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.MiddleDistal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.middleDistal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.MiddleTip, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.middleTip); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.RingMetacarpal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.ringMetacarpal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.RingProximal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.ringProximal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.RingIntermediate, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.ringMiddle); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.RingDistal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.ringDistal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.RingTip, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.ringTip); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.PinkyMetacarpal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.pinkyMetacarpal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.PinkyProximal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.pinkyProximal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.PinkyIntermediate, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.pinkyMiddle); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.PinkyDistal, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.pinkyDistal); AssignHandJoint(fixedHandPose, isLeft, currState.handJoints, HandJointName.PinkyTip, s_tempBoneTransforms, SteamVR_Skeleton_JointIndexes.pinkyTip); } } }
protected void RangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds) { if (rangeOfMotionBlendRoutine != null) { StopCoroutine(rangeOfMotionBlendRoutine); } EVRSkeletalMotionRange oldRangeOfMotion = rangeOfMotion; rangeOfMotion = newRangeOfMotion; if (this.gameObject.activeInHierarchy) { rangeOfMotionBlendRoutine = StartCoroutine(DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds)); } }
void InitController() { HandDebugLog("Connected with type " + handType.ToString()); bool hadOldRendermodel = mainRenderModel != null; EVRSkeletalMotionRange oldRM_rom = EVRSkeletalMotionRange.WithController; if (hadOldRendermodel) { oldRM_rom = mainRenderModel.GetSkeletonRangeOfMotion; } foreach (RenderModel r in renderModels) { if (r != null) { Destroy(r.gameObject); } } renderModels.Clear(); GameObject renderModelInstance = GameObject.Instantiate(renderModelPrefab); renderModelInstance.layer = gameObject.layer; renderModelInstance.tag = gameObject.tag; renderModelInstance.transform.parent = this.transform; renderModelInstance.transform.localPosition = Vector3.zero; renderModelInstance.transform.localRotation = Quaternion.identity; renderModelInstance.transform.localScale = renderModelPrefab.transform.localScale; Player.instance.input_manager.TriggerHapticPulse(this, 800); //pulse on controller init int deviceIndex = trackedObject.GetDeviceIndex(); mainRenderModel = renderModelInstance.GetComponent <RenderModel>(); renderModels.Add(mainRenderModel); if (hadOldRendermodel) { mainRenderModel.SetSkeletonRangeOfMotion(oldRM_rom); } this.BroadcastMessage("SetInputSource", handType, SendMessageOptions.DontRequireReceiver); // let child objects know we've initialized this.BroadcastMessage("OnHandInitialized", deviceIndex, SendMessageOptions.DontRequireReceiver); // let child objects know we've initialized }
private void InitController() { HandDebugLog("Hand " + name + " connected with type " + handType.ToString()); bool hadOldRendermodel = mainRenderModel != null; EVRSkeletalMotionRange oldRM_rom = EVRSkeletalMotionRange.WithController; if (hadOldRendermodel) { oldRM_rom = mainRenderModel.GetSkeletonRangeOfMotion; } if (mainRenderModel != null) { Destroy(mainRenderModel.gameObject); } GameObject renderModelInstance = GameObject.Instantiate(renderModelPrefab); renderModelInstance.layer = gameObject.layer; renderModelInstance.tag = gameObject.tag; renderModelInstance.transform.parent = this.transform; renderModelInstance.transform.localPosition = Vector3.zero; renderModelInstance.transform.localRotation = Quaternion.identity; renderModelInstance.transform.localScale = renderModelPrefab.transform.localScale; //TriggerHapticPulse(800); //pulse on controller init int deviceIndex = trackedObject.GetDeviceIndex(); mainRenderModel = renderModelInstance.GetComponent <RenderModel>(); mainRenderModel.SetPoser(GetComponent <SteamVR_Skeleton_PoserCustom>()); if (hadOldRendermodel) { Debug.Log("setting skeletal range of motion"); mainRenderModel.SetSkeletonRangeOfMotion(oldRM_rom); } this.BroadcastMessage("SetInputSource", handType, SendMessageOptions.DontRequireReceiver); // let child objects know we've initialized this.BroadcastMessage("OnHandInitialized", deviceIndex, SendMessageOptions.DontRequireReceiver); // let child objects know we've initialized }
protected void ResetTemporaryRangeOfMotionBlend(float blendOverSeconds) { if (temporaryRangeOfMotion != null) { if (rangeOfMotionBlendRoutine != null) { StopCoroutine(rangeOfMotionBlendRoutine); } EVRSkeletalMotionRange oldRangeOfMotion = temporaryRangeOfMotion.Value; EVRSkeletalMotionRange newRangeOfMotion = rangeOfMotion; temporaryRangeOfMotion = null; if (this.gameObject.activeInHierarchy) { rangeOfMotionBlendRoutine = StartCoroutine(DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds)); } } }
protected void TemporaryRangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds) { if (rangeOfMotionBlendRoutine != null) { MelonCoroutines.Stop(rangeOfMotionBlendRoutine); } EVRSkeletalMotionRange oldRangeOfMotion = rangeOfMotion; if (temporaryRangeOfMotion != null) { oldRangeOfMotion = temporaryRangeOfMotion.Value; } temporaryRangeOfMotion = newRangeOfMotion; if (this.gameObject.activeInHierarchy) { rangeOfMotionBlendRoutine = DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds); MelonCoroutines.Start(rangeOfMotionBlendRoutine); } }
// Update is called once per frame void Update() { EVRInputError err; if (initialized == false) { if (OpenVR.Input == null) { return; } if (activeActionSetSize == 0) { activeActionSetSize = (uint)(Marshal.SizeOf(typeof(VRActiveActionSet_t))); } if (skeletalActionData_size == 0) { skeletalActionData_size = (uint)Marshal.SizeOf(typeof(InputSkeletalActionData_t)); } if (digitalActionData_size == 0) { digitalActionData_size = (uint)Marshal.SizeOf(typeof(InputDigitalActionData_t)); } if (analogActionData_size == 0) { analogActionData_size = (uint)Marshal.SizeOf(typeof(InputAnalogActionData_t)); } rangeOfMotion = EVRSkeletalMotionRange.WithoutController; skeletalTransformSpace = EVRSkeletalTransformSpace.Parent; var fullPath = SteamVR_Input.GetActionsFilePath(); err = OpenVR.Input.SetActionManifestPath(fullPath); if (err != EVRInputError.None) { Debug.LogError($"<b>[SteamVR]</b> Error loading action manifest into SteamVR: {err}"); } //parse actions.json var json = File.ReadAllText(fullPath); CurrentActionData = JsonUtility.FromJson <SteamVRActions>(json); foreach (var action in CurrentActionData.actions) { err = OpenVR.Input.GetActionHandle(action.name, ref action.handle); if (err != EVRInputError.None) { Debug.LogError($"<b>[SteamVR]</b> GetActionHandle error ({action.name}): {err}"); } } initialized = true; var actionSetPath = CurrentActionData.action_sets.First().name; ulong actionSetHandle = 0; err = OpenVR.Input.GetActionSetHandle(actionSetPath, ref actionSetHandle); if (err != EVRInputError.None) { Debug.LogError($"<b>[SteamVR]</b> GetActionSetHandle error ({actionSetPath}): {err}"); } var inputSourceNames = System.Enum.GetNames(typeof(SteamVR_Input_Sources)); foreach (var inputSourceName in inputSourceNames) { ulong inputSourceHandle = 0; var inputSourcePath = GetPath(inputSourceName); // Any,LeftHand,RightHand,... err = OpenVR.Input.GetInputSourceHandle(inputSourcePath, ref inputSourceHandle); if (err != EVRInputError.None) { Debug.LogError($"<b>[SteamVR]</b> GetInputSourceHandle error ({inputSourcePath}): {err}"); } else { ActionSetList.Add(new VRActionSet { ulActionSet = actionSetHandle, ulRestrictedToDevice = inputSourceHandle, InputSourcePath = inputSourcePath, IsLeft = inputSourcePath.Contains("left") != handSwap, }); } } //UpdateSkeleton(); rawActiveActionSetArray = ActionSetList.Select(d => new VRActiveActionSet_t { ulActionSet = d.ulActionSet, nPriority = 0,//同プライオリティのアクションセットが複数ある場合同時に実行される ulRestrictedToDevice = d.ulRestrictedToDevice }).ToArray(); OpenVR.Compositor.SetTrackingSpace(ETrackingUniverseOrigin.TrackingUniverseStanding); } //すべてのActionSetに対して新しいイベントがないか更新する err = OpenVR.Input.UpdateActionState(rawActiveActionSetArray, activeActionSetSize); if (err != EVRInputError.None) { Debug.LogError($"<b>[SteamVR]</b> UpdateActionState error: {err}"); } foreach (var actionset in ActionSetList) { foreach (var action in CurrentActionData.actions) { if (action.type == "boolean") { //オンオフ系のデータ取得(クリックやタッチ) action.lastDigitalActionData = action.digitalActionData; err = OpenVR.Input.GetDigitalActionData(action.handle, ref action.digitalActionData, digitalActionData_size, actionset.ulRestrictedToDevice); if (err != EVRInputError.None) { Debug.LogWarning($"<b>[SteamVR]</b> GetDigitalActionData error ({action.name}): {err} handle: {action.handle}"); continue; } if (IsKeyDown(action.digitalActionData)) { Debug.Log($"<b>[SteamVR]</b> GetDigitalActionData IsKeyDown ({action.name}): {err} handle: {action.handle}"); bool isTouch = action.ShortName.StartsWith("Touch") && action.ShortName.Contains("Trigger") == false; Vector3 axis = isTouch ? GetLastPosition(action.ShortName) : Vector3.zero; KeyDownEvent?.Invoke(this, new OVRKeyEventArgs(action.ShortName, axis, actionset.IsLeft != handSwap, axis != Vector3.zero, isTouch)); } if (IsKeyUp(action.digitalActionData)) { Debug.Log($"<b>[SteamVR]</b> GetDigitalActionData IsKeyUp ({action.name}): {err} handle: {action.handle}"); bool isTouch = action.ShortName.StartsWith("Touch") && action.ShortName.Contains("Trigger") == false; Vector3 axis = isTouch ? GetLastPosition(action.ShortName) : Vector3.zero; KeyUpEvent?.Invoke(this, new OVRKeyEventArgs(action.ShortName, axis, actionset.IsLeft != handSwap, axis != Vector3.zero, isTouch)); } } else if (action.type == "vector1" || action.type == "vector2" || action.type == "vector3") { //アナログ入力のデータ取得(スティックやタッチパッド) action.lastAnalogActionData = action.analogActionData; err = OpenVR.Input.GetAnalogActionData(action.handle, ref action.analogActionData, analogActionData_size, actionset.ulRestrictedToDevice); if (err != EVRInputError.None) { Debug.LogWarning($"<b>[SteamVR]</b> GetAnalogActionData error ({action.name}): {err} handle: {action.handle}"); continue; } //Debug.Log($"<b>[SteamVR]</b> GetAnalogActionData Position:{action.analogActionData.x},{action.analogActionData.y} ({action.name}): {err} handle: {action.handle}"); var axis = new Vector3(action.analogActionData.x, action.analogActionData.y, action.analogActionData.z); if (axis != Vector3.zero) { LastPositions[action.name] = axis; AxisChangedEvent?.Invoke(this, new OVRKeyEventArgs(action.ShortName, axis, actionset.IsLeft != handSwap, true, false)); } } else if (action.type == "skeleton") { if (EnableSkeletal) { //実際にBoneのTransformを取得する //rangeOfMotionは実際のコントローラーの形に指を曲げる(WithController)か、完全にグーが出来るようにする(WithoutController)か var tempBoneTransforms = new VRBoneTransform_t[SteamVR_Action_Skeleton.numBones]; err = OpenVR.Input.GetSkeletalBoneData(action.handle, skeletalTransformSpace, rangeOfMotion, tempBoneTransforms); if (err != EVRInputError.None) { //特定の条件においてものすごい勢いでログが出る //Debug.LogWarning($"<b>[SteamVR]</b> GetDigitalActionData error ({action.name}): {err} handle: {action.handle}"); continue; } handTracking_Skeletal.SetSkeltalBoneData(action.name.Contains("Left") != handSwap, tempBoneTransforms); } } } } }
protected IEnumerator DoRangeOfMotionBlend(EVRSkeletalMotionRange oldRangeOfMotion, EVRSkeletalMotionRange newRangeOfMotion, float overTime) { float startTime = Time.time; float endTime = startTime + overTime; Vector3[] oldBonePositions; Quaternion[] oldBoneRotations; Vector3[] newBonePositions; Quaternion[] newBoneRotations; while (Time.time < endTime) { yield return(null); float lerp = (Time.time - startTime) / overTime; if (skeletonBlend > 0) { skeletonAction.SetRangeOfMotion(oldRangeOfMotion); skeletonAction.UpdateValueWithoutEvents(); oldBonePositions = (Vector3[])GetBonePositions().Clone(); oldBoneRotations = (Quaternion[])GetBoneRotations().Clone(); skeletonAction.SetRangeOfMotion(newRangeOfMotion); skeletonAction.UpdateValueWithoutEvents(); newBonePositions = GetBonePositions(); newBoneRotations = GetBoneRotations(); for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++) { if (bones[boneIndex] == null) { continue; } if (SteamVR_Utils.IsValid(newBoneRotations[boneIndex]) == false || SteamVR_Utils.IsValid(oldBoneRotations[boneIndex]) == false) { continue; } Vector3 blendedRangeOfMotionPosition = Vector3.Lerp(oldBonePositions[boneIndex], newBonePositions[boneIndex], lerp); Quaternion blendedRangeOfMotionRotation = Quaternion.Lerp(oldBoneRotations[boneIndex], newBoneRotations[boneIndex], lerp); if (skeletonBlend < 1) { if (blendPoser != null) { SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], blendedRangeOfMotionPosition, skeletonBlend)); SetBoneRotation(boneIndex, Quaternion.Lerp(GetBlendPoseForBone(boneIndex, blendedRangeOfMotionRotation), blendedRangeOfMotionRotation, skeletonBlend)); } else { SetBonePosition(boneIndex, Vector3.Lerp(bones[boneIndex].localPosition, blendedRangeOfMotionPosition, skeletonBlend)); SetBoneRotation(boneIndex, Quaternion.Lerp(bones[boneIndex].localRotation, blendedRangeOfMotionRotation, skeletonBlend)); } } else { SetBonePosition(boneIndex, blendedRangeOfMotionPosition); SetBoneRotation(boneIndex, blendedRangeOfMotionRotation); } } } if (onBoneTransformsUpdated != null) { onBoneTransformsUpdated.Invoke(this, inputSource); } if (onBoneTransformsUpdatedEvent != null) { onBoneTransformsUpdatedEvent.Invoke(this, inputSource); } } rangeOfMotionBlendRoutine = null; }
/// <summary> /// Set the range of the motion of the bones in this skeleton. Options are "With Controller" as if your hand is holding your VR controller. /// Or "Without Controller" as if your hand is empty. /// </summary> /// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param> public void SetRangeOfMotion(SteamVR_Input_Sources inputSource, EVRSkeletalMotionRange range) { rangeOfMotion[inputSource] = range; }
protected IEnumerator DoRangeOfMotionBlend(EVRSkeletalMotionRange oldRangeOfMotion, EVRSkeletalMotionRange newRangeOfMotion, float overTime) { var startTime = Time.time; var endTime = startTime + overTime; Vector3[] oldBonePositions; Quaternion[] oldBoneRotations; Vector3[] newBonePositions; Quaternion[] newBoneRotations; while (Time.time < endTime) { yield return(null); var lerp = (Time.time - startTime) / overTime; if (skeletonBlend > 0) { skeletonAction.SetRangeOfMotion(inputSource, oldRangeOfMotion); skeletonAction.UpdateValue(inputSource, true); oldBonePositions = (Vector3[])GetBonePositions(inputSource).Clone(); oldBoneRotations = (Quaternion[])GetBoneRotations(inputSource).Clone(); skeletonAction.SetRangeOfMotion(inputSource, newRangeOfMotion); skeletonAction.UpdateValue(inputSource, true); newBonePositions = GetBonePositions(inputSource); newBoneRotations = GetBoneRotations(inputSource); for (var boneIndex = 0; boneIndex < bones.Length; boneIndex++) { if (bones[boneIndex] == null) { continue; } if (SteamVR_Utils.IsValid(newBoneRotations[boneIndex]) == false || SteamVR_Utils.IsValid(oldBoneRotations[boneIndex]) == false) { continue; } var blendedRangeOfMotionPosition = Vector3.Lerp(oldBonePositions[boneIndex], newBonePositions[boneIndex], lerp); var blendedRangeOfMotionRotation = Quaternion.Lerp(oldBoneRotations[boneIndex], newBoneRotations[boneIndex], lerp); if (skeletonBlend < 1) { SetBonePosition(boneIndex, Vector3.Lerp(bones[boneIndex].localPosition, blendedRangeOfMotionPosition, skeletonBlend)); SetBoneRotation(boneIndex, Quaternion.Lerp(bones[boneIndex].localRotation, blendedRangeOfMotionRotation, skeletonBlend)); } else { SetBonePosition(boneIndex, blendedRangeOfMotionPosition); SetBoneRotation(boneIndex, blendedRangeOfMotionRotation); } } } } rangeOfMotionBlendRoutine = null; }
public void SetLimitRangeOfMotion(bool isShown) { _rangeOfMotion = isShown ? EVRSkeletalMotionRange.WithController : EVRSkeletalMotionRange.WithoutController; _skeleton?.SetRangeOfMotion(_rangeOfMotion); // Back to main menu we have a nullreference here }
public void SetSkeletonRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f) { mainRenderModel.SetSkeletonRangeOfMotion(newRangeOfMotion, blendOverSeconds); }