130 lines
3.5 KiB
C#
130 lines
3.5 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|