|
|
- // Object Control|Locomotion|20060
- namespace VRTK
- {
- using UnityEngine;
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="controlledGameObject">The GameObject that is going to be affected.</param>
- /// <param name="directionDevice">The device that is used for the direction.</param>
- /// <param name="axisDirection">The axis that is being affected.</param>
- /// <param name="axis">The value of the current touchpad touch point based across the axis direction.</param>
- /// <param name="deadzone">The value of the deadzone based across the axis direction.</param>
- /// <param name="currentlyFalling">Whether the controlled GameObject is currently falling.</param>
- /// <param name="modifierActive">Whether the modifier button is pressed.</param>
- public struct ObjectControlEventArgs
- {
- public GameObject controlledGameObject;
- public Transform directionDevice;
- public Vector3 axisDirection;
- public float axis;
- public float deadzone;
- public bool currentlyFalling;
- public bool modifierActive;
- }
-
- /// <summary>
- /// Event Payload
- /// </summary>
- /// <param name="sender">this object</param>
- /// <param name="e"><see cref="ObjectControlEventArgs"/></param>
- public delegate void ObjectControlEventHandler(object sender, ObjectControlEventArgs e);
-
- /// <summary>
- /// Provides a base that all object control locomotions can inherit from.
- /// </summary>
- /// <remarks>
- /// **Script Usage:**
- /// > This is an abstract class that is to be inherited to a concrete class that provides object control locomotion functionality, therefore this script should not be directly used.
- /// </remarks>
- public abstract class VRTK_ObjectControl : MonoBehaviour
- {
- /// <summary>
- /// Devices for providing direction.
- /// </summary>
- public enum DirectionDevices
- {
- /// <summary>
- /// The headset device.
- /// </summary>
- Headset,
- /// <summary>
- /// The left controller device.
- /// </summary>
- LeftController,
- /// <summary>
- /// The right controller device.
- /// </summary>
- RightController,
- /// <summary>
- /// The controlled object.
- /// </summary>
- ControlledObject
- }
-
- [Header("Control Settings")]
-
- [Tooltip("The direction that will be moved in is the direction of this device.")]
- public DirectionDevices deviceForDirection = DirectionDevices.Headset;
- [Tooltip("If this is checked then whenever the axis on the attached controller is being changed, all other object control scripts of the same type on other controllers will be disabled.")]
- public bool disableOtherControlsOnActive = true;
- [Tooltip("If a `VRTK_BodyPhysics` script is present and this is checked, then the object control will affect the play area whilst it is falling.")]
- public bool affectOnFalling = false;
- [Tooltip("An optional game object to apply the object control to. If this is blank then the PlayArea will be controlled.")]
- public GameObject controlOverrideObject;
-
- [Header("Custom Settings")]
-
- [Tooltip("The controller to read the controller events from. If this is blank then it will attempt to get a controller events script from the same GameObject.")]
- public VRTK_ControllerEvents controller;
- [Tooltip("An optional Body Physics script to check for potential collisions in the moving direction.")]
- public VRTK_BodyPhysics bodyPhysics;
-
- /// <summary>
- /// Emitted when the X Axis Changes.
- /// </summary>
- public event ObjectControlEventHandler XAxisChanged;
-
- /// <summary>
- /// Emitted when the Y Axis Changes.
- /// </summary>
- public event ObjectControlEventHandler YAxisChanged;
-
- protected VRTK_ControllerEvents controllerEvents;
- protected VRTK_ObjectControl otherObjectControl;
- protected GameObject controlledGameObject;
- protected GameObject setControlOverrideObject;
- protected Transform directionDevice;
- protected DirectionDevices previousDeviceForDirection;
- protected Vector2 currentAxis;
- protected Vector2 storedAxis;
- protected bool currentlyFalling = false;
- protected bool modifierActive = false;
- protected float controlledGameObjectPreviousY = 0f;
- protected float controlledGameObjectPreviousYOffset = 0.01f;
-
- public virtual void OnXAxisChanged(ObjectControlEventArgs e)
- {
- if (XAxisChanged != null)
- {
- XAxisChanged(this, e);
- }
- }
-
- public virtual void OnYAxisChanged(ObjectControlEventArgs e)
- {
- if (YAxisChanged != null)
- {
- YAxisChanged(this, e);
- }
- }
-
- protected abstract void ControlFixedUpdate();
- protected abstract VRTK_ObjectControl GetOtherControl();
- protected abstract bool IsInAction();
- protected abstract void SetListeners(bool state);
-
- protected virtual void Awake()
- {
- VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void OnEnable()
- {
- currentAxis = Vector2.zero;
- storedAxis = Vector2.zero;
- controllerEvents = (controller != null ? controller : GetComponentInParent<VRTK_ControllerEvents>());
- if (!controllerEvents)
- {
- VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_NOT_INJECTED, "VRTK_ObjectControl", "VRTK_ControllerEvents", "controller", "the same"));
- return;
- }
- SetControlledObject();
- bodyPhysics = (!controlOverrideObject ? (bodyPhysics != null ? bodyPhysics : FindObjectOfType<VRTK_BodyPhysics>()) : null);
-
- directionDevice = GetDirectionDevice();
- SetListeners(true);
- otherObjectControl = GetOtherControl();
- }
-
- protected virtual void OnDisable()
- {
- SetListeners(false);
- }
-
- protected virtual void OnDestroy()
- {
- VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
- }
-
- protected virtual void Update()
- {
- if (controlOverrideObject != setControlOverrideObject)
- {
- SetControlledObject();
- }
- }
-
- protected virtual void FixedUpdate()
- {
- CheckDirectionDevice();
- CheckFalling();
- ControlFixedUpdate();
- }
-
- protected virtual ObjectControlEventArgs SetEventArguements(Vector3 axisDirection, float axis, float axisDeadzone)
- {
- ObjectControlEventArgs e;
- e.controlledGameObject = controlledGameObject;
- e.directionDevice = directionDevice;
- e.axisDirection = axisDirection;
- e.axis = axis;
- e.deadzone = axisDeadzone;
- e.currentlyFalling = currentlyFalling;
- e.modifierActive = modifierActive;
-
- return e;
- }
-
- protected virtual void SetControlledObject()
- {
- Transform playArea = VRTK_DeviceFinder.PlayAreaTransform();
-
- setControlOverrideObject = controlOverrideObject;
- controlledGameObject = (controlOverrideObject ? controlOverrideObject : (playArea != null ? playArea.gameObject : null));
- if (controlledGameObject != null)
- {
- controlledGameObjectPreviousY = controlledGameObject.transform.position.y;
- }
- }
-
- protected virtual void CheckFalling()
- {
- if (bodyPhysics != null && bodyPhysics.IsFalling() && ObjectHeightChange())
- {
- if (!affectOnFalling)
- {
- if (storedAxis == Vector2.zero)
- {
- storedAxis = new Vector2(currentAxis.x, currentAxis.y);
- }
- currentAxis = Vector2.zero;
- }
- currentlyFalling = true;
- }
-
- if (bodyPhysics != null && !bodyPhysics.IsFalling() && currentlyFalling)
- {
- currentAxis = (IsInAction() ? storedAxis : Vector2.zero);
- storedAxis = Vector2.zero;
- currentlyFalling = false;
- }
- }
-
- protected virtual bool ObjectHeightChange()
- {
- bool heightChanged = ((controlledGameObjectPreviousY - controlledGameObjectPreviousYOffset) > controlledGameObject.transform.position.y);
- controlledGameObjectPreviousY = controlledGameObject.transform.position.y;
- return heightChanged;
- }
-
- protected virtual Transform GetDirectionDevice()
- {
- switch (deviceForDirection)
- {
- case DirectionDevices.ControlledObject:
- return controlledGameObject.transform;
- case DirectionDevices.Headset:
- return VRTK_DeviceFinder.HeadsetTransform();
- case DirectionDevices.LeftController:
- return VRTK_DeviceFinder.GetControllerLeftHand(true).transform;
- case DirectionDevices.RightController:
- return VRTK_DeviceFinder.GetControllerRightHand(true).transform;
- }
-
- return null;
- }
-
- protected virtual void CheckDirectionDevice()
- {
- if (previousDeviceForDirection != deviceForDirection)
- {
- directionDevice = GetDirectionDevice();
- }
-
- previousDeviceForDirection = deviceForDirection;
- }
- }
- }
|