diff --git a/Assets/VRTK/Documentation/API.md b/Assets/VRTK/Documentation/API.md index c94e6bebf..d3765be9e 100644 --- a/Assets/VRTK/Documentation/API.md +++ b/Assets/VRTK/Documentation/API.md @@ -6530,6 +6530,7 @@ A collection of scripts that provide useful functionality to aid the creation pr * [Transform Follow](#transform-follow-vrtk_transformfollow) * [SDK Object Alias](#sdk-object-alias-vrtk_sdkobjectalias) * [SDK Transform Modify](#sdk-transform-modify-vrtk_sdktransformmodify) + * [SDK Object State](#sdk-object-state-vrtk_sdkobjectstate) * [Velocity Estimator](#velocity-estimator-vrtk_velocityestimator) --- @@ -7768,6 +7769,40 @@ The UpdateTransform method updates the Transform data on the current GameObject --- +## SDK Object State (VRTK_SDKObjectState) + +### Overview + +The SDK Object State script can be used to set the enable/active state of a GameObject or Component based on SDK information. + +The state can be determined by: +* The current loaded SDK setup. +* The current attached Headset type. +* The current attached Controller type. + +### Inspector Parameters + + * **Target:** The GameObject or Component that is the target of the enable/disable action. If this is left blank then the GameObject that the script is attached to will be used as the `Target`. + * **Object State:** The state to set the `Target` to when this script is enabled. Checking this box will enable/activate the `Target`, unchecking will disable/deactivate the `Target`. + * **Loaded SDK Setup:** If the currently loaded SDK Setup matches the one provided here then the `Target` state will be set to the desired `Object State`. + * **Headset Type:** If the attached headset type matches the selected headset then the `Target` state will be set to the desired `Object State`. + * **Controller Type:** If the current controller type matches the selected controller type then the `Target` state will be set to the desired `Object State`. + +### Class Methods + +#### SetStateByControllerReference/1 + + > `public virtual void SetStateByControllerReference(VRTK_ControllerReference controllerReference)` + + * Parameters + * `VRTK_ControllerReference controllerReference` - A controller reference to check for the controller type of. + * Returns + * _none_ + +The SetStateByControllerReference method sets the object state based on the controller type of the given controller reference. + +--- + ## Velocity Estimator (VRTK_VelocityEstimator) ### Overview diff --git a/Assets/VRTK/Source/Scripts/Internal/VRTK_TrackedController.cs b/Assets/VRTK/Source/Scripts/Internal/VRTK_TrackedController.cs index e2395febe..780352e8a 100644 --- a/Assets/VRTK/Source/Scripts/Internal/VRTK_TrackedController.cs +++ b/Assets/VRTK/Source/Scripts/Internal/VRTK_TrackedController.cs @@ -101,6 +101,7 @@ protected virtual void OnEnable() protected virtual void OnDisable() { CancelCoroutines(); + index = uint.MaxValue; ManageControllerModelListeners(false); OnControllerDisabled(SetEventPayload()); } diff --git a/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs new file mode 100644 index 000000000..81c4e949d --- /dev/null +++ b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs @@ -0,0 +1,171 @@ +// SDK Object State|Utilities|90160 +namespace VRTK +{ + using UnityEngine; + using System.Collections; + using System.Reflection; + + /// + /// The SDK Object State script can be used to set the enable/active state of a GameObject or Component based on SDK information. + /// + /// + /// The state can be determined by: + /// * The current loaded SDK setup. + /// * The current attached Headset type. + /// * The current attached Controller type. + /// + [AddComponentMenu("VRTK/Scripts/Utilities/VRTK_SDKObjectState")] + public class VRTK_SDKObjectState : MonoBehaviour + { + [Header("Target Settings")] + + [Tooltip("The GameObject or Component that is the target of the enable/disable action. If this is left blank then the GameObject that the script is attached to will be used as the `Target`.")] + public Object target = null; + [Tooltip("The state to set the `Target` to when this script is enabled. Checking this box will enable/activate the `Target`, unchecking will disable/deactivate the `Target`.")] + public bool objectState = false; + [Tooltip("If the currently loaded SDK Setup matches the one provided here then the `Target` state will be set to the desired `Object State`.")] + public VRTK_SDKSetup loadedSDKSetup = null; + [Tooltip("If the attached headset type matches the selected headset then the `Target` state will be set to the desired `Object State`.")] + public VRTK_DeviceFinder.Headsets headsetType = VRTK_DeviceFinder.Headsets.Unknown; + [Tooltip("If the current controller type matches the selected controller type then the `Target` state will be set to the desired `Object State`.")] + public SDK_BaseController.ControllerType controllerType = SDK_BaseController.ControllerType.Undefined; + + protected VRTK_SDKManager sdkManager; + protected Coroutine checkToggleRoutine; + //TODO: REPLACE WITH GENERIC CONTROLLER TYPE AVAILABLE EVENT + protected int findControllerAttempts = 100; + protected float findControllerAttemptsDelay = 0.1f; + protected Coroutine attemptFindControllerModel; + + /// + /// The SetStateByControllerReference method sets the object state based on the controller type of the given controller reference. + /// + /// A controller reference to check for the controller type of. + public virtual void SetStateByControllerReference(VRTK_ControllerReference controllerReference) + { + if (VRTK_ControllerReference.IsValid(controllerReference)) + { + SDK_BaseController.ControllerType foundControllerType = VRTK_DeviceFinder.GetCurrentControllerType(controllerReference); + if (foundControllerType != SDK_BaseController.ControllerType.Undefined && controllerType == foundControllerType) + { + ToggleObject(); + } + } + } + + protected virtual void OnEnable() + { + sdkManager = VRTK_SDKManager.instance; + target = (target != null ? target : gameObject); + sdkManager.LoadedSetupChanged += LoadedSetupChanged; + checkToggleRoutine = StartCoroutine(CheckToggleAtEndOfFrame()); + } + + protected virtual void OnDisable() + { + sdkManager.LoadedSetupChanged -= LoadedSetupChanged; + if (checkToggleRoutine != null) + { + StopCoroutine(checkToggleRoutine); + } + if (attemptFindControllerModel != null) + { + StopCoroutine(attemptFindControllerModel); + } + } + + protected virtual IEnumerator CheckToggleAtEndOfFrame() + { + yield return new WaitForEndOfFrame(); + CheckToggle(); + } + + protected virtual void LoadedSetupChanged(VRTK_SDKManager sender, VRTK_SDKManager.LoadedSetupChangeEventArgs e) + { + CheckToggle(); + } + + protected virtual void CheckToggle() + { + ToggleOnSDK(); + ToggleOnHeadset(); + ToggleOnController(); + } + + protected virtual void ToggleOnSDK() + { + if (loadedSDKSetup != null && loadedSDKSetup == sdkManager.loadedSetup) + { + ToggleObject(); + } + } + + protected virtual void ToggleOnHeadset() + { + if (headsetType != VRTK_DeviceFinder.Headsets.Unknown && headsetType == VRTK_DeviceFinder.GetHeadsetType(true)) + { + ToggleObject(); + } + } + + protected virtual void ToggleOnController() + { + if (controllerType != SDK_BaseController.ControllerType.Undefined) + { + attemptFindControllerModel = StartCoroutine(AttemptFindController(findControllerAttempts, findControllerAttemptsDelay)); + } + } + + protected virtual IEnumerator AttemptFindController(int attempts, float delay) + { + WaitForSeconds delayInstruction = new WaitForSeconds(delay); + SDK_BaseController.ControllerType foundControllerType = VRTK_DeviceFinder.GetCurrentControllerType(); + + while (foundControllerType == SDK_BaseController.ControllerType.Undefined && attempts > 0) + { + foundControllerType = VRTK_DeviceFinder.GetCurrentControllerType(); + attempts--; + yield return delayInstruction; + } + + if (foundControllerType != SDK_BaseController.ControllerType.Undefined && controllerType == foundControllerType) + { + ToggleObject(); + } + } + + protected virtual void ToggleObject() + { + if (target is GameObject) + { + ToggleGameObject(); + } + else if (target.GetType().IsSubclassOf(typeof(Component))) + { + ToggleComponent(); + } + } + + protected virtual void ToggleGameObject() + { + if (target != null) + { + GameObject toggleTarget = (GameObject)target; + toggleTarget.SetActive(objectState); + } + } + + protected virtual void ToggleComponent() + { + if (target != null) + { + Component toggleTarget = (Component)target; + PropertyInfo property = toggleTarget.GetType().GetProperty("enabled"); + if (property != null) + { + property.SetValue(toggleTarget, objectState, null); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs.meta b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs.meta new file mode 100644 index 000000000..de60f0486 --- /dev/null +++ b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a2da120c864326344b626f18a3c39765 +timeCreated: 1504447113 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 9fc9cd059ece45b40827fa0850950687, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKTransformModify.cs b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKTransformModify.cs index 4ffc7ed1e..e5567186a 100644 --- a/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKTransformModify.cs +++ b/Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKTransformModify.cs @@ -38,7 +38,8 @@ public class VRTK_SDKTransformModify : MonoBehaviour public List sdkOverrides = new List(); protected VRTK_SDKManager sdkManager; - protected int findControllerAttempts = 25; + //TODO: REPLACE WITH GENERIC CONTROLLER TYPE AVAILABLE EVENT + protected int findControllerAttempts = 100; protected float findControllerAttemptsDelay = 0.1f; protected Coroutine attemptFindControllerModel;