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;