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; } } } }