using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI; public class ChildAnimController : MonoBehaviour { [Header("Animations")] [SerializeField] private string idleAnimation1 = "idle_m_2_220f"; [SerializeField] private string idleAnimation2 = "idle_selfcheck_1_300f"; [SerializeField] private string walkAnimation = "locom_m_basicWalk_30f"; [SerializeField] private string talkingAnimation = "idle_phoneTalking_180f"; [Header("Movement Points")] [SerializeField] private Transform targetPoint1; [SerializeField] private Transform targetPoint2; [Header("Light Check")] [SerializeField] private LightManager lightManager; [SerializeField] private int requiredLights = 9; [SerializeField] private string successMessage = "Чудово! Презентуй перед класом свою думку!"; [SerializeField] private string failMessage = "Ти ще не завершив завдання, спробуй ще!"; [Header("Movement Settings")] [SerializeField] private float walkSpeed = 1f; [SerializeField] private float waitTime = 3f; [SerializeField] private float rotationSpeed = 5f; [SerializeField] private float gravity = 9.81f; [SerializeField] private float stopDistance = 0.25f; [Header("Dialogue Settings")] [SerializeField] private float talkDuration = 7f; [SerializeField] private float interactionCooldown = 10f; [SerializeField] private float textHeight = 1f; [SerializeField] private GameObject existingCanvas; [SerializeField] private TextMeshProUGUI existingTextMesh; private Animator _animator; private CharacterController _characterController; private bool _isTalking; private bool _canInteract = true; private float _verticalVelocity; private Transform _player; private Coroutine _walkRoutine; private void Start() { _animator = GetComponent(); _characterController = GetComponent(); if (_characterController == null) { _characterController = gameObject.AddComponent(); _characterController.height = 1f; _characterController.radius = 0.3f; _characterController.center = new Vector3(0f, 0.5f, 0f); } if (existingCanvas != null) { existingCanvas.transform.SetParent(transform); existingCanvas.transform.localPosition = new Vector3(0f, textHeight, 0f); existingCanvas.SetActive(false); } _walkRoutine = StartCoroutine(WalkRoutine()); } private void Update() { if (existingCanvas != null && existingCanvas.activeSelf) { Camera cam = Camera.main; if (cam != null) { Vector3 dir = existingCanvas.transform.position - cam.transform.position; if (dir != Vector3.zero) existingCanvas.transform.rotation = Quaternion.LookRotation(dir); } } } private IEnumerator WalkRoutine() { while (true) { if (_isTalking) { yield return null; continue; } PlayAnimation(idleAnimation1); yield return new WaitForSeconds(waitTime); if (targetPoint1 != null) { yield return WalkToPoint(targetPoint1.position); yield return TurnToFaceDirection(targetPoint2 != null ? targetPoint2.position : transform.forward); } if (_isTalking) continue; PlayAnimation(idleAnimation2); yield return new WaitForSeconds(waitTime); if (targetPoint2 != null) { yield return WalkToPoint(targetPoint2.position); yield return TurnToFaceDirection(targetPoint1 != null ? targetPoint1.position : transform.forward); } } } private IEnumerator WalkToPoint(Vector3 targetPosition) { PlayAnimation(walkAnimation); while (true) { if (_isTalking) yield break; Vector3 fromXZ = new Vector3(transform.position.x, 0f, transform.position.z); Vector3 toXZ = new Vector3(targetPosition.x, 0f, targetPosition.z); float dist = Vector3.Distance(fromXZ, toXZ); if (dist <= stopDistance) { _verticalVelocity = -0.5f; yield break; } Vector3 dir = (toXZ - fromXZ).normalized; if (dir != Vector3.zero) { Quaternion look = Quaternion.LookRotation(dir); transform.rotation = Quaternion.Slerp(transform.rotation, look, rotationSpeed * Time.deltaTime); } if (_characterController.isGrounded) _verticalVelocity = -0.5f; else _verticalVelocity -= gravity * Time.deltaTime; Vector3 move = dir * walkSpeed; move.y = _verticalVelocity; _characterController.Move(move * Time.deltaTime); yield return null; } } private IEnumerator TurnToFaceDirection(Vector3 targetPosition) { Vector3 dir = targetPosition - transform.position; dir.y = 0f; if (dir == Vector3.zero) yield break; Quaternion targetRot = Quaternion.LookRotation(dir.normalized); while (Quaternion.Angle(transform.rotation, targetRot) > 1f) { if (_isTalking) yield break; transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rotationSpeed * Time.deltaTime); yield return null; } } private void OnTriggerEnter(Collider other) { if (!other.CompareTag("Player")) return; if (!_canInteract) return; if (_isTalking) return; _player = other.transform; StartCoroutine(TalkToPlayer()); } private IEnumerator TalkToPlayer() { _isTalking = true; _canInteract = false; if (_walkRoutine != null) StopCoroutine(_walkRoutine); if (_player != null) { Vector3 dir = _player.position - transform.position; dir.y = 0f; if (dir != Vector3.zero) transform.rotation = Quaternion.LookRotation(dir.normalized); } PlayAnimation(talkingAnimation); if (existingTextMesh != null) { if (lightManager != null && lightManager.CurrentLights >= requiredLights) existingTextMesh.text = successMessage; else existingTextMesh.text = failMessage; } if (existingCanvas != null) existingCanvas.SetActive(true); yield return new WaitForSeconds(talkDuration); EndTalk(); } private void EndTalk() { if (existingCanvas != null) existingCanvas.SetActive(false); _isTalking = false; StartCoroutine(CooldownRoutine()); _walkRoutine = StartCoroutine(WalkRoutine()); } private IEnumerator CooldownRoutine() { yield return new WaitForSeconds(interactionCooldown); _canInteract = true; } private void PlayAnimation(string animationName) { if (_animator == null) return; if (string.IsNullOrEmpty(animationName)) return; _animator.CrossFade(animationName, 0.2f); } }