Skip to content

Commit

Permalink
feat(Utilities): ability to change object state based on loaded sdk
Browse files Browse the repository at this point in the history
The new SDK Object State script allows the state of a GameObject or
Component to be set to enabled/active or disabled based on the
SDK information.

This can be useful for toggling certain settings for different SDK
types, headsets or connected controllers.
  • Loading branch information
thestonefox committed Sep 3, 2017
1 parent 5d73db2 commit b352322
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 1 deletion.
35 changes: 35 additions & 0 deletions Assets/VRTK/Documentation/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

---
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ protected virtual void OnEnable()
protected virtual void OnDisable()
{
CancelCoroutines();
index = uint.MaxValue;
ManageControllerModelListeners(false);
OnControllerDisabled(SetEventPayload());
}
Expand Down
171 changes: 171 additions & 0 deletions Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// SDK Object State|Utilities|90160
namespace VRTK
{
using UnityEngine;
using System.Collections;
using System.Reflection;

/// <summary>
/// The SDK Object State script can be used to set the enable/active state of a GameObject or Component based on SDK information.
/// </summary>
/// <remarks>
/// The state can be determined by:
/// * The current loaded SDK setup.
/// * The current attached Headset type.
/// * The current attached Controller type.
/// </remarks>
[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;

/// <summary>
/// The SetStateByControllerReference method sets the object state based on the controller type of the given controller reference.
/// </summary>
/// <param name="controllerReference">A controller reference to check for the controller type of.</param>
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);
}
}
}
}
}
12 changes: 12 additions & 0 deletions Assets/VRTK/Source/Scripts/Utilities/VRTK_SDKObjectState.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public class VRTK_SDKTransformModify : MonoBehaviour
public List<VRTK_SDKTransformModifiers> sdkOverrides = new List<VRTK_SDKTransformModifiers>();

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;

Expand Down

0 comments on commit b352322

Please sign in to comment.