99 lines
2.5 KiB
C#
99 lines
2.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.XR.Interaction.Toolkit;
|
|
|
|
public class SteeringKeyXR : MonoBehaviour
|
|
{
|
|
[Header("References")]
|
|
[SerializeField] private UnityEngine.XR.Interaction.Toolkit.Interactables.XRGrabInteractable grabInteractable;
|
|
[SerializeField] private Transform keyPivot;
|
|
|
|
[Header("Steering")]
|
|
[SerializeField] private float maxAngle = 45f;
|
|
|
|
[Header("Return")]
|
|
[SerializeField] private bool returnToCenter = true;
|
|
[SerializeField] private float returnSpeed = 5f;
|
|
|
|
private Transform currentInteractor;
|
|
private bool isGrabbed;
|
|
|
|
private Quaternion initialPivotRotation;
|
|
private float currentAngle;
|
|
|
|
public float SteeringValue
|
|
{
|
|
get
|
|
{
|
|
return Mathf.Clamp(currentAngle / maxAngle, -1f, 1f);
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (keyPivot == null)
|
|
keyPivot = transform;
|
|
|
|
initialPivotRotation = keyPivot.localRotation;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (grabInteractable != null)
|
|
{
|
|
grabInteractable.selectEntered.AddListener(OnGrab);
|
|
grabInteractable.selectExited.AddListener(OnRelease);
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (grabInteractable != null)
|
|
{
|
|
grabInteractable.selectEntered.RemoveListener(OnGrab);
|
|
grabInteractable.selectExited.RemoveListener(OnRelease);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (isGrabbed && currentInteractor != null)
|
|
{
|
|
UpdateAngleFromHand();
|
|
}
|
|
else if (returnToCenter)
|
|
{
|
|
currentAngle = Mathf.Lerp(currentAngle, 0f, returnSpeed * Time.deltaTime);
|
|
ApplyRotation();
|
|
}
|
|
}
|
|
|
|
private void OnGrab(SelectEnterEventArgs args)
|
|
{
|
|
isGrabbed = true;
|
|
currentInteractor = args.interactorObject.transform;
|
|
}
|
|
|
|
private void OnRelease(SelectExitEventArgs args)
|
|
{
|
|
isGrabbed = false;
|
|
currentInteractor = null;
|
|
}
|
|
|
|
private void UpdateAngleFromHand()
|
|
{
|
|
Vector3 worldDir = currentInteractor.position - keyPivot.position;
|
|
Vector3 localDir = keyPivot.InverseTransformDirection(worldDir);
|
|
|
|
float targetAngle = Mathf.Atan2(localDir.x, localDir.z) * Mathf.Rad2Deg;
|
|
|
|
currentAngle = Mathf.Clamp(targetAngle, -maxAngle, maxAngle);
|
|
|
|
ApplyRotation();
|
|
}
|
|
|
|
private void ApplyRotation()
|
|
{
|
|
keyPivot.localRotation =
|
|
initialPivotRotation * Quaternion.Euler(0f, currentAngle, 0f);
|
|
}
|
|
} |