using UnityEngine; namespace GamingIsLove.ORKFramework.Components { [AddComponentMenu("ORK Framework/Camera Control/Camera Look At Movement")] public class CameraLookAtMovement : MonoBehaviour { [SerializeField] private bool useTag = false; [SerializeField] private string targetTag = "Player"; [SerializeField] private string targetName = "Player"; [SerializeField, Range(0.1f, 10f)] private float turnSpeed = 3f; [SerializeField, Range(0f, 5f)] private float minMovementSpeed = 0.5f; [SerializeField, Range(0f, 20f)] private float lookaheadDistance = 5f; [SerializeField] private Vector3 rotationAxis = Vector3.up; private GameObject targetObject; private Vector3 currentMovementDirection; private Vector3 lastPosition; private void Start() { FindTarget(); if (targetObject == null) { Debug.LogError("CameraLookAtMovement: Target not found! " + (useTag ? ("Tag: " + targetTag) : ("Name: " + targetName))); enabled = false; return; } lastPosition = targetObject.transform.position; } // Поиск цели по тегу или имени private void FindTarget() { if (useTag) { targetObject = GameObject.FindGameObjectWithTag(targetTag); } else { targetObject = GameObject.Find(targetName); } } private void LateUpdate() { if (targetObject == null) return; UpdateMovementDirection(); RotateCameraTowardsMovement(); } private void UpdateMovementDirection() { Vector3 newPosition = targetObject.transform.position; Vector3 movement = newPosition - lastPosition; // Отладка Debug.Log("Time.deltaTime: " + Time.deltaTime); Debug.Log("Movement raw: " + movement); float speed = 0f; if (Time.deltaTime > 0.0001f) speed = movement.magnitude / Time.deltaTime; Debug.Log($"Speed: {speed:F3} | Movement mag: {movement.magnitude:F3}"); lastPosition = newPosition; // Нормализация с защитой от нулевого вектора if (movement.magnitude > 0.001f) { currentMovementDirection = movement.normalized; Debug.Log("Normalized: " + currentMovementDirection); } else { currentMovementDirection = targetObject.transform.forward; Debug.Log("Using forward: " + currentMovementDirection); } } private void RotateCameraTowardsMovement() { Vector3 lookAtPoint = targetObject.transform.position + currentMovementDirection * lookaheadDistance; Vector3 directionToLookAt = lookAtPoint - transform.position; directionToLookAt.y = 0; if (directionToLookAt == Vector3.zero) return; Quaternion targetRotation = Quaternion.LookRotation(directionToLookAt, rotationAxis); transform.rotation = Quaternion.Slerp( transform.rotation, targetRotation, turnSpeed * Time.deltaTime ); } public void SetTarget(GameObject newTarget) { targetObject = newTarget; if (targetObject != null) lastPosition = targetObject.transform.position; } } }