266 lines
6.1 KiB
C#
266 lines
6.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
public class PlayerChairSeat : MonoBehaviour
|
|
{
|
|
[Header("XR Player")]
|
|
public Transform xrOrigin;
|
|
public Camera xrCamera;
|
|
|
|
[Header("Seat Point")]
|
|
public Transform seatHeadPoint;
|
|
|
|
[Header("Release Point")]
|
|
public Transform releasePoint;
|
|
public bool moveToReleasePointOnRelease = true;
|
|
|
|
[Header("VR Interaction Check")]
|
|
public bool useDistanceCheck = true;
|
|
public float sitDistance = 2f;
|
|
|
|
[Header("Lock While Seated")]
|
|
public bool lockXROriginWhileSeated = true;
|
|
|
|
[Header("Release Move Check")]
|
|
public bool hideUIWhenPlayerMovesAfterRelease = true;
|
|
public float moveDetectDistance = 0.15f;
|
|
|
|
[Header("Disable Movement While Seated")]
|
|
public Behaviour[] disableWhileSeated;
|
|
|
|
[Header("Seat Interaction Zone")]
|
|
public GameObject[] disableObjectsAfterSeated;
|
|
public Collider[] disableCollidersAfterSeated;
|
|
public Behaviour[] disableBehavioursAfterSeated;
|
|
|
|
[Header("Events")]
|
|
public UnityEvent onSeated;
|
|
public UnityEvent onReleased;
|
|
public UnityEvent onMovedAfterRelease;
|
|
|
|
private bool isSeated = false;
|
|
private bool isReleased = false;
|
|
private bool movedAfterReleaseEventCalled = false;
|
|
|
|
private CharacterController characterController;
|
|
|
|
private Vector3 lockedOriginPosition;
|
|
private Quaternion lockedOriginRotation;
|
|
|
|
private Vector3 releaseOriginPosition;
|
|
|
|
void Start()
|
|
{
|
|
if (xrOrigin != null)
|
|
{
|
|
characterController = xrOrigin.GetComponent<CharacterController>();
|
|
}
|
|
|
|
SetSeatInteractionZoneActive(true);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
CheckMoveAfterRelease();
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if (!isSeated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!lockXROriginWhileSeated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (xrOrigin == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
xrOrigin.position = lockedOriginPosition;
|
|
xrOrigin.rotation = lockedOriginRotation;
|
|
}
|
|
|
|
public void SitDown()
|
|
{
|
|
if (isSeated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (xrOrigin == null || xrCamera == null || seatHeadPoint == null)
|
|
{
|
|
Debug.LogWarning("XR Origin / XR Camera / Seat Head Point ¿¬°á ¾È µÊ");
|
|
return;
|
|
}
|
|
|
|
if (useDistanceCheck)
|
|
{
|
|
float distance = Vector3.Distance(xrCamera.transform.position, seatHeadPoint.position);
|
|
|
|
if (distance > sitDistance)
|
|
{
|
|
Debug.Log("Too far from chair to sit.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
isSeated = true;
|
|
isReleased = false;
|
|
movedAfterReleaseEventCalled = false;
|
|
|
|
foreach (Behaviour behaviour in disableWhileSeated)
|
|
{
|
|
if (behaviour != null)
|
|
{
|
|
behaviour.enabled = false;
|
|
}
|
|
}
|
|
|
|
if (characterController != null)
|
|
{
|
|
characterController.enabled = false;
|
|
}
|
|
|
|
float cameraYaw = xrCamera.transform.eulerAngles.y;
|
|
float targetYaw = seatHeadPoint.eulerAngles.y;
|
|
float yawOffset = targetYaw - cameraYaw;
|
|
|
|
xrOrigin.RotateAround(xrCamera.transform.position, Vector3.up, yawOffset);
|
|
|
|
Vector3 offset = seatHeadPoint.position - xrCamera.transform.position;
|
|
xrOrigin.position += offset;
|
|
|
|
lockedOriginPosition = xrOrigin.position;
|
|
lockedOriginRotation = xrOrigin.rotation;
|
|
|
|
if (characterController != null)
|
|
{
|
|
characterController.enabled = true;
|
|
}
|
|
|
|
SetSeatInteractionZoneActive(false);
|
|
|
|
Debug.Log("Player seated and locked.");
|
|
|
|
onSeated?.Invoke();
|
|
}
|
|
|
|
public void ReleaseSeat()
|
|
{
|
|
if (!isSeated)
|
|
{
|
|
Debug.Log("ReleaseSeat called, but player is not seated.");
|
|
return;
|
|
}
|
|
|
|
isSeated = false;
|
|
isReleased = true;
|
|
movedAfterReleaseEventCalled = false;
|
|
|
|
if (characterController != null)
|
|
{
|
|
characterController.enabled = false;
|
|
}
|
|
|
|
if (moveToReleasePointOnRelease && releasePoint != null && xrOrigin != null)
|
|
{
|
|
xrOrigin.position = releasePoint.position;
|
|
xrOrigin.rotation = releasePoint.rotation;
|
|
}
|
|
|
|
if (characterController != null)
|
|
{
|
|
characterController.enabled = true;
|
|
}
|
|
|
|
if (xrOrigin != null)
|
|
{
|
|
releaseOriginPosition = xrOrigin.position;
|
|
}
|
|
|
|
foreach (Behaviour behaviour in disableWhileSeated)
|
|
{
|
|
if (behaviour != null)
|
|
{
|
|
behaviour.enabled = true;
|
|
}
|
|
}
|
|
|
|
SetSeatInteractionZoneActive(true);
|
|
|
|
Debug.Log("Player released from seat.");
|
|
|
|
onReleased?.Invoke();
|
|
}
|
|
|
|
void SetSeatInteractionZoneActive(bool active)
|
|
{
|
|
foreach (GameObject obj in disableObjectsAfterSeated)
|
|
{
|
|
if (obj != null)
|
|
{
|
|
obj.SetActive(active);
|
|
}
|
|
}
|
|
|
|
foreach (Collider col in disableCollidersAfterSeated)
|
|
{
|
|
if (col != null)
|
|
{
|
|
col.enabled = active;
|
|
}
|
|
}
|
|
|
|
foreach (Behaviour behaviour in disableBehavioursAfterSeated)
|
|
{
|
|
if (behaviour != null)
|
|
{
|
|
behaviour.enabled = active;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CheckMoveAfterRelease()
|
|
{
|
|
if (!hideUIWhenPlayerMovesAfterRelease)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!isReleased)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (movedAfterReleaseEventCalled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (xrOrigin == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float distance = Vector3.Distance(xrOrigin.position, releaseOriginPosition);
|
|
|
|
if (distance >= moveDetectDistance)
|
|
{
|
|
movedAfterReleaseEventCalled = true;
|
|
|
|
Debug.Log("Player moved after release. Hide game UI.");
|
|
|
|
onMovedAfterRelease?.Invoke();
|
|
}
|
|
}
|
|
|
|
public bool IsSeated()
|
|
{
|
|
return isSeated;
|
|
}
|
|
} |