namespace VRTK { using UnityEngine; using System.Collections; public struct VRTKTrackedControllerEventArgs { public uint currentIndex; public uint previousIndex; } public delegate void VRTKTrackedControllerEventHandler(object sender, VRTKTrackedControllerEventArgs e); public class VRTK_TrackedController : MonoBehaviour { public uint index = uint.MaxValue; public event VRTKTrackedControllerEventHandler ControllerEnabled; public event VRTKTrackedControllerEventHandler ControllerDisabled; public event VRTKTrackedControllerEventHandler ControllerIndexChanged; public event VRTKTrackedControllerEventHandler ControllerModelAvailable; protected GameObject aliasController; protected SDK_BaseController.ControllerType controllerType = SDK_BaseController.ControllerType.Undefined; protected bool controllerModelWaitSubscribed = false; protected Coroutine emitControllerEnabledRoutine = null; protected Coroutine emitControllerModelAvailableRoutine = null; protected VRTK_ControllerReference controllerReference { get { return VRTK_ControllerReference.GetControllerReference(index); } } public virtual void OnControllerEnabled(VRTKTrackedControllerEventArgs e) { if (ControllerEnabled != null) { ControllerEnabled(this, e); } } public virtual void OnControllerDisabled(VRTKTrackedControllerEventArgs e) { if (ControllerDisabled != null) { ControllerDisabled(this, e); } } public virtual void OnControllerIndexChanged(VRTKTrackedControllerEventArgs e) { if (ControllerIndexChanged != null) { ControllerIndexChanged(this, e); } } public virtual void OnControllerModelAvailable(VRTKTrackedControllerEventArgs e) { if (ControllerModelAvailable != null) { ControllerModelAvailable(this, e); } } public virtual SDK_BaseController.ControllerType GetControllerType() { return controllerType; } protected virtual VRTKTrackedControllerEventArgs SetEventPayload(uint previousIndex = uint.MaxValue) { VRTKTrackedControllerEventArgs e; e.currentIndex = index; e.previousIndex = previousIndex; return e; } protected virtual void Awake() { VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this); } protected virtual void OnEnable() { aliasController = VRTK_DeviceFinder.GetScriptAliasController(gameObject); if (aliasController == null) { aliasController = gameObject; } index = VRTK_DeviceFinder.GetControllerIndex(gameObject); SetControllerType(); StartEmitControllerEnabledAtEndOfFrame(); ManageControllerModelListeners(true); } protected virtual void OnDisable() { CancelCoroutines(); index = uint.MaxValue; ManageControllerModelListeners(false); OnControllerDisabled(SetEventPayload()); } protected virtual void OnDestroy() { VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this); } protected virtual void FixedUpdate() { VRTK_SDK_Bridge.ControllerProcessFixedUpdate(VRTK_ControllerReference.GetControllerReference(index)); } protected virtual void Update() { uint checkIndex = VRTK_DeviceFinder.GetControllerIndex(gameObject); if (checkIndex != index) { uint previousIndex = index; index = checkIndex; //If the controller model listeners have already been registered, then make sure to unsub and sub when index changes. if (controllerModelWaitSubscribed) { ManageControllerModelListeners(false); ManageControllerModelListeners(true); } OnControllerIndexChanged(SetEventPayload(previousIndex)); SetControllerType(); } VRTK_SDK_Bridge.ControllerProcessUpdate(VRTK_ControllerReference.GetControllerReference(index)); if (aliasController != null && gameObject.activeInHierarchy && !aliasController.activeSelf) { aliasController.SetActive(true); } } protected virtual void ManageLeftControllerListener(bool register, VRTKSDKBaseControllerEventHandler callbackMethod) { if (register) { VRTK_SDK_Bridge.GetControllerSDK().LeftControllerModelReady += callbackMethod; } else { VRTK_SDK_Bridge.GetControllerSDK().LeftControllerModelReady -= callbackMethod; } } protected virtual void ManageRightControllerListener(bool register, VRTKSDKBaseControllerEventHandler callbackMethod) { if (register) { VRTK_SDK_Bridge.GetControllerSDK().RightControllerModelReady += callbackMethod; } else { VRTK_SDK_Bridge.GetControllerSDK().RightControllerModelReady -= callbackMethod; } } protected virtual void RegisterHandControllerListener(bool register, SDK_BaseController.ControllerHand givenHand) { switch (givenHand) { case SDK_BaseController.ControllerHand.Left: ManageLeftControllerListener(register, ControllerModelReady); break; case SDK_BaseController.ControllerHand.Right: ManageRightControllerListener(register, ControllerModelReady); break; } controllerModelWaitSubscribed = register; } protected virtual void ManageControllerModelListener(bool register, SDK_BaseController.ControllerHand givenHand) { if (VRTK_SDK_Bridge.WaitForControllerModel(givenHand)) { RegisterHandControllerListener(register, givenHand); } else { if (register) { StartEmitControllerModelReadyAtEndOfFrame(); } else if (controllerModelWaitSubscribed) { RegisterHandControllerListener(register, givenHand); } } } protected virtual void ManageControllerModelListeners(bool register) { ManageControllerModelListener(register, VRTK_DeviceFinder.GetControllerHand(gameObject)); } protected virtual void SetControllerType() { controllerType = (controllerReference != null ? VRTK_DeviceFinder.GetCurrentControllerType(controllerReference) : SDK_BaseController.ControllerType.Undefined); } protected virtual void StartEmitControllerEnabledAtEndOfFrame() { if (gameObject.activeInHierarchy) { emitControllerEnabledRoutine = StartCoroutine(EmitControllerEnabledAtEndOfFrame()); } } protected virtual IEnumerator EmitControllerEnabledAtEndOfFrame() { yield return new WaitForEndOfFrame(); OnControllerEnabled(SetEventPayload()); } protected virtual void ControllerModelReady(object sender, VRTKSDKBaseControllerEventArgs e) { SetControllerType(); if (e.controllerReference == null || controllerReference == e.controllerReference) { StartEmitControllerModelReadyAtEndOfFrame(); } } protected virtual void StartEmitControllerModelReadyAtEndOfFrame() { if (gameObject != null && gameObject.activeInHierarchy) { emitControllerModelAvailableRoutine = StartCoroutine(EmitControllerModelReadyAtEndOfFrame()); } } protected virtual IEnumerator EmitControllerModelReadyAtEndOfFrame() { yield return new WaitForEndOfFrame(); OnControllerModelAvailable(SetEventPayload()); } protected virtual void CancelCoroutines() { if (emitControllerModelAvailableRoutine != null) { StopCoroutine(emitControllerModelAvailableRoutine); } if (emitControllerEnabledRoutine != null) { StopCoroutine(emitControllerEnabledRoutine); } } } }