using System.Collections; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; public class HookWalkToTable : MonoBehaviour { [Header("Path Points")] public Transform tableFrontPoint; public Transform chairFrontPoint; [Header("Sit / Stand Point")] public Transform sitPoint; public Transform standPoint; [Header("Move Setting")] public float arriveBuffer = 0.15f; public float navMeshSampleDistance = 1.5f; [Header("Animator")] public Animator animator; public string walkBoolName = "isWalking"; public string sitTriggerName = "sitTrigger"; public string standTriggerName = "standTrigger"; [Header("Force Stand Animation")] public bool forcePlayStandState = true; public string standStateName = "Sit To Stand 0"; [Header("Stand Up Setting")] public float standUpDuration = 1.5f; public bool disableAgentAfterStandUp = true; [Header("After Match")] public bool blockWalkingAfterStandUp = true; [Header("Collision")] public bool disableCollidersWhenSitting = true; public bool enableCollidersAfterStandUp = true; public Collider[] hookColliders; [Header("Test")] public Key testStartKey = Key.T; public Key testStandUpKey = Key.Y; private NavMeshAgent agent; private int step = 0; private bool isMoving = false; private bool isSitting = false; private bool isStandingUp = false; private bool hasStoodUpAfterMatch = false; private Vector3 currentDestination; private void Start() { agent = GetComponent(); if (animator == null) { animator = GetComponentInChildren(); } if (agent != null) { agent.isStopped = true; agent.ResetPath(); agent.stoppingDistance = 0.05f; agent.autoBraking = true; } if (animator != null) { animator.applyRootMotion = false; animator.SetBool(walkBoolName, false); animator.ResetTrigger(sitTriggerName); animator.ResetTrigger(standTriggerName); } else { Debug.LogWarning("Hook Animator is missing."); } if (hookColliders == null || hookColliders.Length == 0) { hookColliders = GetComponentsInChildren(); } Debug.Log("HookWalkToTable ready."); } private void Update() { if (Keyboard.current != null && Keyboard.current[testStartKey].wasPressedThisFrame) { StartWalking(); } if (Keyboard.current != null && Keyboard.current[testStandUpKey].wasPressedThisFrame) { StandUp(); } if (!isMoving || agent == null || !agent.enabled) { return; } if (agent.pathPending) { return; } float distance = Vector3.Distance(transform.position, currentDestination); if (distance <= agent.stoppingDistance + arriveBuffer) { GoNextStep(); } } public void StartWalking() { if (blockWalkingAfterStandUp && hasStoodUpAfterMatch) { Debug.Log("Hook already stood up after match. StartWalking ignored."); return; } if (agent == null) { Debug.LogWarning("NavMeshAgent is missing."); return; } if (tableFrontPoint == null || chairFrontPoint == null) { Debug.LogWarning("TableFrontPoint or ChairFrontPoint is missing."); return; } if (isMoving || isSitting || isStandingUp) { Debug.Log("Hook cannot start walking now."); return; } step = 0; isMoving = true; EnableHookColliders(); if (animator != null) { animator.applyRootMotion = false; animator.ResetTrigger(sitTriggerName); animator.ResetTrigger(standTriggerName); animator.SetBool(walkBoolName, true); } if (!agent.enabled) { agent.enabled = true; } agent.isStopped = false; MoveTo(tableFrontPoint); Debug.Log("Hook starts walking to table front point."); } private void MoveTo(Transform target) { if (target == null) { Debug.LogWarning("Move target is null."); StopWalking(); return; } NavMeshHit hit; if (NavMesh.SamplePosition(target.position, out hit, navMeshSampleDistance, NavMesh.AllAreas)) { currentDestination = hit.position; agent.SetDestination(currentDestination); Debug.Log("Destination set: " + target.name); } else { Debug.LogWarning("Target is not near NavMesh: " + target.name); StopWalking(); } } private void GoNextStep() { step++; if (step == 1) { MoveTo(chairFrontPoint); Debug.Log("Hook moves to chair front point."); } else { ArriveAndSit(); } } private void ArriveAndSit() { isMoving = false; isSitting = true; isStandingUp = false; if (agent != null && agent.enabled) { agent.isStopped = true; agent.ResetPath(); agent.enabled = false; } if (disableCollidersWhenSitting) { DisableHookColliders(); } if (sitPoint != null) { transform.SetPositionAndRotation(sitPoint.position, sitPoint.rotation); } else if (chairFrontPoint != null) { transform.rotation = chairFrontPoint.rotation; } if (animator != null) { animator.applyRootMotion = false; animator.SetBool(walkBoolName, false); animator.ResetTrigger(standTriggerName); animator.ResetTrigger(sitTriggerName); Debug.Log("Sit trigger call: " + sitTriggerName); animator.SetTrigger(sitTriggerName); } Debug.Log("Hook moved to sit point and started sitting."); } public void StandUp() { if (isStandingUp) { Debug.Log("Hook is already standing up."); return; } if (!isSitting) { Debug.LogWarning("Hook is not sitting. StandUp ignored."); return; } StartCoroutine(StandUpRoutine()); } private IEnumerator StandUpRoutine() { isStandingUp = true; isSitting = false; isMoving = false; if (agent != null && agent.enabled) { agent.isStopped = true; agent.ResetPath(); agent.enabled = false; } if (animator != null) { animator.applyRootMotion = false; animator.SetBool(walkBoolName, false); animator.ResetTrigger(sitTriggerName); animator.ResetTrigger(standTriggerName); Debug.Log("Stand trigger call: " + standTriggerName); animator.SetTrigger(standTriggerName); if (forcePlayStandState && !string.IsNullOrEmpty(standStateName)) { animator.CrossFadeInFixedTime(standStateName, 0.08f, 0); Debug.Log("Force play stand state: " + standStateName); } } Debug.Log("Hook started stand up animation."); yield return new WaitForSeconds(standUpDuration); if (standPoint != null) { transform.SetPositionAndRotation(standPoint.position, standPoint.rotation); } if (enableCollidersAfterStandUp) { EnableHookColliders(); } if (agent != null) { if (disableAgentAfterStandUp) { agent.enabled = false; } else { if (!agent.enabled) { agent.enabled = true; } agent.isStopped = true; agent.ResetPath(); } } hasStoodUpAfterMatch = true; isStandingUp = false; Debug.Log("Hook stood up."); } public void ResetHookAfterMatchBlock() { hasStoodUpAfterMatch = false; Debug.Log("Hook StartWalking block reset."); } private void StopWalking() { isMoving = false; if (agent != null && agent.enabled) { agent.isStopped = true; agent.ResetPath(); } if (animator != null) { animator.SetBool(walkBoolName, false); } } private void DisableHookColliders() { if (hookColliders == null || hookColliders.Length == 0) { return; } foreach (Collider col in hookColliders) { if (col != null) { col.enabled = false; } } } private void EnableHookColliders() { if (hookColliders == null || hookColliders.Length == 0) { return; } foreach (Collider col in hookColliders) { if (col != null) { col.enabled = true; } } } }