Files
FORT-BO/Assets/CONTENT/FEATURES/MapRadar/MapCoordinateSystem.cs
T
AsanoRema ffa1064063 Squashed commit of the following:
commit 428243f4a6
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Sat Aug 29 13:43:13 2026 +0300

    Squashed commit of the following:

    commit 68e78fa464
    Author: AsanoRema <asanorema2036@gmail.com>
    Date:   Sat Aug 29 13:41:49 2026 +0300

        Updated .gitignore

commit 9f87122a34
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Sat Aug 29 13:34:57 2026 +0300

    Added Dohya

commit f6a7547e84
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Fri Aug 21 17:59:13 2026 +0300

    Fixed

commit b98901c366
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Tue Aug 18 17:37:22 2026 +0300

    Added new particle Package

commit bb2f4a3b16
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Tue Aug 18 17:17:48 2026 +0300

    Map mehanic ready to multiplayer

commit c01ff800f6
Author: AsanoRema <asanorema2036@gmail.com>
Date:   Tue Aug 18 16:16:19 2026 +0300

    Squashed commit of the following:

    commit 173bbb165c
    Author: henjkey <henjkey@gmail.com>
    Date:   Fri Aug 14 18:51:23 2026 +0500

        Mappp

    commit d559ab338a
    Author: henjkey <henjkey@gmail.com>
    Date:   Thu Aug 13 18:42:41 2026 +0500

        Map

        Controller
        Coordinates
        Target System
        Crosshair System
        Radar System
2026-08-29 13:45:55 +03:00

148 lines
6.0 KiB
C#

using UnityEngine;
[DisallowMultipleComponent]
public sealed class MapCoordinateSystem : MonoBehaviour
{
public const float CoordinateMaximum = 10f;
[Header("Coordinate Bounds")]
[SerializeField] private Transform bottomLeft = null;
[SerializeField] private Transform bottomRight = null;
[SerializeField] private Transform topLeft = null;
[SerializeField] private Transform topRight = null;
[Header("Square Bounds")]
[SerializeField, Min(0.001f)] private float squareSize = 5.14925f;
[Header("Scene View Visualization")]
[SerializeField] private bool showSceneVisualization = true;
[SerializeField, Range(1, 20)] private int gridDivisions = 10;
[SerializeField] private bool showCoordinateLabels = true;
[SerializeField] private Color boundaryColor = new(0f, 0.85f, 1f, 1f);
[SerializeField] private Color gridColor = new(0f, 0.85f, 1f, 0.3f);
[SerializeField, Min(0.001f)] private float markerSize = 0.06f;
public Vector2 MaximumCoordinates => new(CoordinateMaximum, CoordinateMaximum);
public float SquareSize => Mathf.Max(0.001f, squareSize);
public bool ShowSceneVisualization => showSceneVisualization;
public int GridDivisions => Mathf.Max(1, gridDivisions);
public bool ShowCoordinateLabels => showCoordinateLabels;
public Color BoundaryColor => boundaryColor;
public Color GridColor => gridColor;
public float MarkerSize => Mathf.Max(0.001f, markerSize);
public Transform BottomLeft => bottomLeft;
public Transform BottomRight => bottomRight;
public Transform TopLeft => topLeft;
public Transform TopRight => topRight;
private void OnValidate()
{
squareSize = Mathf.Max(0.001f, squareSize);
ApplySquareBounds();
}
public void ApplySquareBounds()
{
if (!HasValidCorners())
return;
Vector3 origin = bottomLeft.position;
Vector3 rightDirection = bottomRight.position - origin;
Vector3 upDirection = topLeft.position - origin;
if (rightDirection.sqrMagnitude <= Mathf.Epsilon || upDirection.sqrMagnitude <= Mathf.Epsilon)
return;
rightDirection.Normalize();
upDirection = Vector3.ProjectOnPlane(upDirection, rightDirection);
if (upDirection.sqrMagnitude <= Mathf.Epsilon)
return;
upDirection.Normalize();
float size = SquareSize;
bottomRight.position = origin + rightDirection * size;
topLeft.position = origin + upDirection * size;
topRight.position = origin + (rightDirection + upDirection) * size;
}
public Vector2 ClampCoordinates(Vector2 coordinates)
{
return new Vector2(
Mathf.Clamp(coordinates.x, 0f, CoordinateMaximum),
Mathf.Clamp(coordinates.y, 0f, CoordinateMaximum));
}
public Vector3 CoordinatesToWorldPosition(Vector2 coordinates)
{
if (!HasValidCorners())
return transform.position;
Vector2 clamped = ClampCoordinates(coordinates);
float horizontal = clamped.x / CoordinateMaximum;
float vertical = clamped.y / CoordinateMaximum;
Vector3 bottom = Vector3.Lerp(bottomLeft.position, bottomRight.position, horizontal);
Vector3 top = Vector3.Lerp(topLeft.position, topRight.position, horizontal);
return Vector3.Lerp(bottom, top, vertical);
}
public Vector2 WorldPositionToCoordinates(Vector3 worldPosition)
{
if (!HasValidCorners())
return Vector2.zero;
Vector3 horizontalEdge = bottomRight.position - bottomLeft.position;
Vector3 verticalEdge = topLeft.position - bottomLeft.position;
Vector3 fromBottomLeft = worldPosition - bottomLeft.position;
float horizontal = horizontalEdge.sqrMagnitude > Mathf.Epsilon
? Vector3.Dot(fromBottomLeft, horizontalEdge) / horizontalEdge.sqrMagnitude
: 0f;
float vertical = verticalEdge.sqrMagnitude > Mathf.Epsilon
? Vector3.Dot(fromBottomLeft, verticalEdge) / verticalEdge.sqrMagnitude
: 0f;
for (int iteration = 0; iteration < 6; iteration++)
{
Vector3 current = BilinearPosition(horizontal, vertical);
Vector3 error = worldPosition - current;
Vector3 horizontalDerivative = Vector3.Lerp(
bottomRight.position - bottomLeft.position,
topRight.position - topLeft.position,
vertical);
Vector3 verticalDerivative = Vector3.Lerp(
topLeft.position - bottomLeft.position,
topRight.position - bottomRight.position,
horizontal);
float horizontalLength = Vector3.Dot(horizontalDerivative, horizontalDerivative);
float mixedLength = Vector3.Dot(horizontalDerivative, verticalDerivative);
float verticalLength = Vector3.Dot(verticalDerivative, verticalDerivative);
float determinant = horizontalLength * verticalLength - mixedLength * mixedLength;
if (Mathf.Abs(determinant) <= Mathf.Epsilon)
break;
float horizontalError = Vector3.Dot(horizontalDerivative, error);
float verticalError = Vector3.Dot(verticalDerivative, error);
horizontal += (horizontalError * verticalLength - verticalError * mixedLength) / determinant;
vertical += (verticalError * horizontalLength - horizontalError * mixedLength) / determinant;
}
Vector2 coordinates = new(
horizontal * CoordinateMaximum,
vertical * CoordinateMaximum);
return ClampCoordinates(coordinates);
}
private Vector3 BilinearPosition(float horizontal, float vertical)
{
Vector3 bottom = Vector3.LerpUnclamped(bottomLeft.position, bottomRight.position, horizontal);
Vector3 top = Vector3.LerpUnclamped(topLeft.position, topRight.position, horizontal);
return Vector3.LerpUnclamped(bottom, top, vertical);
}
public bool HasValidCorners()
{
return bottomLeft != null && bottomRight != null && topLeft != null && topRight != null;
}
}