157 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
public class RadarOrigin : MonoBehaviour
{
public float Radius = 500f;
[Header("Gizmos Settings")]
[SerializeField] private bool showCenterPoint = true;
[SerializeField] private bool showCircle = true;
[SerializeField] private bool showRadialLines = true;
[SerializeField] private bool showRadiusLabel = true;
[SerializeField] private Color centerColor = Color.red;
[SerializeField] private Color circleColor = Color.green;
[SerializeField] private Color radialLinesColor = new Color(0, 1, 0, 0.3f);
[SerializeField] private Color labelColor = Color.white;
[SerializeField] private float centerPointSize = 5f;
[SerializeField][Range(8, 128)] private int circleSegments = 64;
[SerializeField][Range(1, 8)] private int radialLinesCount = 4;
public bool TransformInFOV(Transform target, float searchAngleOffset, float leftAngleZoneDeg = 5, float rightAngleZoneDeg = 0)
{
if (target == null) return false;
Vector3 directionToTarget = target.position - transform.position;
float angleToTarget = Vector3.SignedAngle(transform.forward, directionToTarget, Vector3.up);
float minAngle = searchAngleOffset - leftAngleZoneDeg;
float maxAngle = searchAngleOffset + rightAngleZoneDeg;
// Отсекаем по углу
if (angleToTarget < minAngle || angleToTarget > maxAngle)
return false;
//Отсекаем по дистанции
float sqrDistance = (target.position - transform.position).sqrMagnitude;
if (sqrDistance > Radius * Radius)
return false;
return true;
}
public Vector3 TransformOnRadar(Transform target)
{
if (target == null) return Vector3.zero;
// Получаем направление до цели
Vector3 directionToTarget = target.position - transform.position;
// Вычисляем расстояние и нормализуем его в диапазон [0, 1]
float distance = directionToTarget.magnitude;
float normalizedDistance = Mathf.Clamp01(distance / Radius);
// Вычисляем угол относительно forward (в градусах)
float angle = Vector3.SignedAngle(transform.forward, directionToTarget, Vector3.up);
// Преобразуем угол в радианы для тригонометрических функций
float angleRad = angle * Mathf.Deg2Rad;
// Вычисляем координаты на радаре (XZ плоскость -> XY плоскость радара)
float x = Mathf.Sin(angleRad) * normalizedDistance;
float y = Mathf.Cos(angleRad) * normalizedDistance;
// МАППИНГ: Yaw объекта (поворот по Y) -> поворот иконки по Z
// Получаем угол поворота цели в горизонтальной плоскости
float targetYaw = target.eulerAngles.y;
float originYaw = transform.eulerAngles.y;
// Вычисляем относительный поворот
float relativeYaw = targetYaw - originYaw;
// Нормализуем угол в диапазон [-180, 180]
relativeYaw = NormalizeAngle(relativeYaw);
// Возвращаем: x, y - позиция на радаре, z - поворот иконки (маппинг Yaw -> Z)
return new Vector3(x, y, relativeYaw);
}
private float NormalizeAngle(float angle)
{
angle = angle % 360;
if (angle > 180) angle -= 360;
if (angle < -180) angle += 360;
return angle;
}
private void OnDrawGizmosSelected()
{
if (!enabled) return;
Vector3 center = transform.position;
Vector3 circleCenter = new Vector3(center.x, center.y, center.z);
// Рисуем центральную точку
if (showCenterPoint)
{
Gizmos.color = centerColor;
Gizmos.DrawSphere(center, centerPointSize);
}
// Рисуем окружность
if (showCircle)
{
Gizmos.color = circleColor;
DrawCircleXZ(circleCenter, Radius, circleSegments);
}
// Рисуем радиальные линии
if (showRadialLines)
{
Gizmos.color = radialLinesColor;
for (int i = 0; i < radialLinesCount; i++)
{
float angle = i * Mathf.PI * 2f / radialLinesCount + Mathf.PI / 2;
float x = Mathf.Cos(angle) * Radius;
float z = Mathf.Sin(angle) * Radius;
Vector3 point = circleCenter + new Vector3(x, 0, z);
Gizmos.DrawLine(center, point);
}
}
// Рисуем текст с радиусом
if (showRadiusLabel)
{
#if UNITY_EDITOR
UnityEditor.Handles.BeginGUI();
Vector3 labelPosition = circleCenter + new Vector3(0, 2, Radius + 10);
Vector3 screenPos = UnityEditor.HandleUtility.WorldToGUIPoint(labelPosition);
GUIStyle style = new GUIStyle();
style.normal.textColor = labelColor;
style.fontSize = 12;
style.fontStyle = FontStyle.Bold;
GUI.Label(new Rect(screenPos.x, screenPos.y, 100, 20), $"Radius: {Radius:F1}", style);
UnityEditor.Handles.EndGUI();
#endif
}
void DrawCircleXZ(Vector3 center, float radius, int segments)
{
Vector3 previousPoint = center + new Vector3(radius, 0, 0);
for (int i = 1; i <= segments; i++)
{
float angle = i * Mathf.PI * 2f / segments;
float x = Mathf.Cos(angle) * radius;
float z = Mathf.Sin(angle) * radius;
Vector3 currentPoint = center + new Vector3(x, 0, z);
Gizmos.DrawLine(previousPoint, currentPoint);
previousPoint = currentPoint;
}
}
}
}