// Base Object Control Action|ObjectControlActions|25000
namespace VRTK
{
using UnityEngine;
///
/// The Base Object Control Action script is an abstract class that all object control action scripts inherit.
///
///
/// As this is an abstract class, it cannot be applied directly to a game object and performs no logic.
///
public abstract class VRTK_BaseObjectControlAction : MonoBehaviour
{
public enum AxisListeners
{
XAxisChanged,
YAxisChanged
}
[Tooltip("The Object Control script to receive axis change events from.")]
public VRTK_ObjectControl objectControlScript;
[Tooltip("Determines which Object Control Axis event to listen to.")]
public AxisListeners listenOnAxisChange;
protected Collider centerCollider;
protected Vector3 colliderCenter = Vector3.zero;
protected float colliderRadius = 0f;
protected float colliderHeight = 0f;
protected Transform controlledTransform;
protected Transform playArea;
protected abstract void Process(GameObject controlledGameObject, Transform directionDevice, Vector3 axisDirection, float axis, float deadzone, bool currentlyFalling, bool modifierActive);
protected virtual void Awake()
{
VRTK_SDKManager.instance.AddBehaviourToToggleOnLoadedSetupChange(this);
}
protected virtual void OnEnable()
{
playArea = VRTK_DeviceFinder.PlayAreaTransform();
if (objectControlScript)
{
switch (listenOnAxisChange)
{
case AxisListeners.XAxisChanged:
objectControlScript.XAxisChanged += AxisChanged;
break;
case AxisListeners.YAxisChanged:
objectControlScript.YAxisChanged += AxisChanged;
break;
}
}
}
protected virtual void OnDisable()
{
if (objectControlScript)
{
switch (listenOnAxisChange)
{
case AxisListeners.XAxisChanged:
objectControlScript.XAxisChanged -= AxisChanged;
break;
case AxisListeners.YAxisChanged:
objectControlScript.YAxisChanged -= AxisChanged;
break;
}
}
}
protected virtual void OnDestroy()
{
VRTK_SDKManager.instance.RemoveBehaviourToToggleOnLoadedSetupChange(this);
}
protected virtual void AxisChanged(object sender, ObjectControlEventArgs e)
{
Process(e.controlledGameObject, e.directionDevice, e.axisDirection, e.axis, e.deadzone, e.currentlyFalling, e.modifierActive);
}
protected virtual void RotateAroundPlayer(GameObject controlledGameObject, float angle)
{
Vector3 objectCenter = GetObjectCenter(controlledGameObject.transform);
Vector3 objectPosition = controlledGameObject.transform.TransformPoint(objectCenter);
controlledGameObject.transform.Rotate(Vector3.up, angle);
objectPosition -= controlledGameObject.transform.TransformPoint(objectCenter);
controlledGameObject.transform.position += objectPosition;
}
protected virtual void Blink(float blinkSpeed)
{
if (blinkSpeed > 0f)
{
VRTK_SDK_Bridge.HeadsetFade(Color.black, 0);
ReleaseBlink(blinkSpeed);
}
}
protected virtual void ReleaseBlink(float blinkSpeed)
{
VRTK_SDK_Bridge.HeadsetFade(Color.clear, blinkSpeed);
}
protected virtual Vector3 GetObjectCenter(Transform checkObject)
{
if (centerCollider == null || checkObject != controlledTransform)
{
controlledTransform = checkObject;
if (checkObject == playArea)
{
CapsuleCollider playAreaCollider = playArea.GetComponentInChildren();
centerCollider = playAreaCollider;
if (playAreaCollider != null)
{
colliderRadius = playAreaCollider.radius;
colliderHeight = playAreaCollider.height;
colliderCenter = playAreaCollider.center;
}
else
{
VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_GAMEOBJECT, "PlayArea", "CapsuleCollider", "the same or child"));
}
}
else
{
centerCollider = checkObject.GetComponentInChildren();
if (centerCollider == null)
{
VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_GAMEOBJECT, "CheckObject", "Collider", "the same or child"));
}
colliderRadius = 0.1f;
colliderHeight = 0.1f;
}
}
return colliderCenter;
}
protected virtual int GetAxisDirection(float axis)
{
int axisDirection = 0;
if (axis < 0)
{
axisDirection = -1;
}
else if (axis > 0)
{
axisDirection = 1;
}
return axisDirection;
}
protected virtual bool CanMove(VRTK_BodyPhysics givenBodyPhysics, Vector3 currentPosition, Vector3 proposedPosition)
{
if (givenBodyPhysics == null)
{
return true;
}
Vector3 proposedDirection = (proposedPosition - currentPosition).normalized;
float distance = Vector3.Distance(currentPosition, proposedPosition);
return !givenBodyPhysics.SweepCollision(proposedDirection, distance);
}
}
}