using UnityEngine; using DG.Tweening; using UnityEngine.Animations; public class CharacterMovement : MonoBehaviour { public enum MovementState { Walking, RotatingToSit, PlayingAnimation, Finished } public MovementState state = MovementState.Walking; [Header("Waypoints")] public Transform[] waypoints; private int currentWaypoint = 0; [Header("References")] public GameObject rigWithAnimator; public Animator animator; public CameraController cameraController; public CameraHeadBobbing cameraHeadBobbing; public Transform mainCamera; // Camera.main.transform public Transform cameraSitTarget; // Dummy camera transform [Header("Settings")] public float moveSpeed = 2f; public float rotationSpeed = 5f; private string currentAnimName = ""; private bool animStarted = false; private bool cameraTransitionStarted = false; private Quaternion targetSitRotation; bool isStarted = false; void Start() { if (waypoints == null || waypoints.Length == 0) { Debug.LogError("No waypoints assigned."); enabled = false; return; } if (animator == null && rigWithAnimator != null) { animator = rigWithAnimator.GetComponentInChildren(); } if (animator == null) { Debug.LogError("Animator not found."); enabled = false; return; } animator.applyRootMotion = false; } public void AnimationStarter() { animator.SetTrigger("StartWalking"); isStarted = true; } void Update() { if (isStarted) { switch (state) { case MovementState.Walking: MoveToWaypoint(); break; case MovementState.RotatingToSit: RotateToSit(); break; case MovementState.PlayingAnimation: WaitForAnimationToEnd(); break; case MovementState.Finished: break; } } } void MoveToWaypoint() { if (currentWaypoint >= waypoints.Length) { state = MovementState.Finished; return; } Transform target = waypoints[currentWaypoint]; Vector3 direction = target.position - transform.position; direction.y = 0; if (direction.magnitude > 0.05f) { transform.position += direction.normalized * moveSpeed * Time.deltaTime; Quaternion lookRot = Quaternion.LookRotation(direction); transform.rotation = Quaternion.Slerp(transform.rotation, lookRot, rotationSpeed * Time.deltaTime); } else { if (currentWaypoint == waypoints.Length - 1) { // Prepare to sit transform.position = target.position; targetSitRotation = target.rotation; state = MovementState.RotatingToSit; } currentWaypoint++; } } void RotateToSit() { transform.rotation = Quaternion.RotateTowards( transform.rotation, targetSitRotation, 300f * Time.deltaTime ); float angle = Quaternion.Angle(transform.rotation, targetSitRotation); if (angle < 2f) { transform.rotation = targetSitRotation; animator.applyRootMotion = true; PlayAnimation("SitDown"); // Disable camera bobbing if (cameraHeadBobbing != null) cameraHeadBobbing.enabled = false; state = MovementState.PlayingAnimation; } } void PlayAnimation(string animName) { animator.SetTrigger(animName); currentAnimName = animName; animStarted = false; } void WaitForAnimationToEnd() { AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); if (!animStarted && stateInfo.IsName(currentAnimName)) { animStarted = true; } else if (animStarted && stateInfo.normalizedTime >= 1f && stateInfo.IsName(currentAnimName)) { if (currentAnimName == "SitDown" && !cameraTransitionStarted && mainCamera != null && cameraSitTarget != null) { cameraTransitionStarted = true; // Move and rotate camera to final cinematic zoom position mainCamera.GetComponent().constraintActive = false; mainCamera.DOMove(cameraSitTarget.position, 1f); mainCamera.DORotate(cameraSitTarget.eulerAngles, 1f) .OnComplete(() => { state = MovementState.Finished; }); } } } }