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; } }