84 lines
2.2 KiB
C#
84 lines
2.2 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
public class PlayerPushToPoint : MonoBehaviour
|
|
{
|
|
[Header("Player")]
|
|
[SerializeField] private Transform xrOrigin;
|
|
[SerializeField] private Transform playerCamera;
|
|
[SerializeField] private CharacterController characterController;
|
|
|
|
[Header("Target")]
|
|
[SerializeField] private Transform pushDirectionPoint;
|
|
|
|
[Header("Push")]
|
|
[SerializeField] private float pushDuration = 0.2f;
|
|
|
|
private bool hasPushed;
|
|
private bool isPushing;
|
|
|
|
// 타임라인에서 충돌 순간에 호출
|
|
public void PushPlayerOnce()
|
|
{
|
|
if (hasPushed || isPushing)
|
|
return;
|
|
|
|
if (xrOrigin == null || playerCamera == null || pushDirectionPoint == null)
|
|
{
|
|
Debug.LogWarning("플레이어 밀기 설정이 비어 있습니다.");
|
|
return;
|
|
}
|
|
|
|
hasPushed = true;
|
|
StartCoroutine(PushRoutine());
|
|
}
|
|
|
|
private IEnumerator PushRoutine()
|
|
{
|
|
isPushing = true;
|
|
|
|
// 카메라의 현재 위치가 목표 지점까지 가기 위해 필요한 이동량
|
|
Vector3 totalMovement =
|
|
pushDirectionPoint.position - playerCamera.position;
|
|
|
|
// VR 플레이어 높이는 변경하지 않음
|
|
totalMovement.y = 0f;
|
|
|
|
float elapsed = 0f;
|
|
Vector3 movedAmount = Vector3.zero;
|
|
|
|
while (elapsed < pushDuration)
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
|
|
float t = Mathf.Clamp01(elapsed / pushDuration);
|
|
|
|
// 처음에 빠르게 밀리고 끝에서 부드럽게 멈춤
|
|
float easedT = 1f - Mathf.Pow(1f - t, 3f);
|
|
|
|
Vector3 targetMovement = totalMovement * easedT;
|
|
Vector3 frameMovement = targetMovement - movedAmount;
|
|
|
|
if (characterController != null &&
|
|
characterController.enabled)
|
|
{
|
|
characterController.Move(frameMovement);
|
|
}
|
|
else
|
|
{
|
|
xrOrigin.position += frameMovement;
|
|
}
|
|
|
|
movedAmount = targetMovement;
|
|
yield return null;
|
|
}
|
|
|
|
isPushing = false;
|
|
}
|
|
|
|
// 반복 테스트할 때만 사용
|
|
public void ResetPush()
|
|
{
|
|
hasPushed = false;
|
|
}
|
|
} |