using UnityEngine; [DisallowMultipleComponent] public sealed class MapTarget : MonoBehaviour { [Header("Map Position (Runtime)")] [SerializeField] private Vector2 mapCoordinates; private MapCoordinateSystem coordinateSystem; private Vector2 movementDirection; private float movementSpeed; private bool isConfigured; private Renderer[] targetRenderers; public Vector2 MapCoordinates => mapCoordinates; public MapCoordinateSystem CoordinateSystem => coordinateSystem; public void Configure( MapCoordinateSystem newCoordinateSystem, Vector2 startCoordinates, float newMovementSpeed, Vector2 initialDirection) { coordinateSystem = newCoordinateSystem; movementSpeed = Mathf.Max(0f, newMovementSpeed); movementDirection = initialDirection.sqrMagnitude > Mathf.Epsilon ? initialDirection.normalized : Vector2.right; isConfigured = coordinateSystem != null && coordinateSystem.HasValidCorners(); SetMapCoordinates(startCoordinates); } private void Update() { if (!isConfigured || movementSpeed <= 0f) return; Vector2 nextCoordinates = mapCoordinates + movementDirection * (movementSpeed * Time.deltaTime); ReflectAtMapBounds(ref nextCoordinates); SetMapCoordinates(nextCoordinates); } public void SetMapCoordinates(Vector2 coordinates) { mapCoordinates = coordinateSystem != null ? coordinateSystem.ClampCoordinates(coordinates) : new Vector2( Mathf.Clamp(coordinates.x, 0f, MapCoordinateSystem.CoordinateMaximum), Mathf.Clamp(coordinates.y, 0f, MapCoordinateSystem.CoordinateMaximum)); if (isConfigured) transform.position = coordinateSystem.CoordinatesToWorldPosition(mapCoordinates); } public Vector2 GetMapCoordinates() { return mapCoordinates; } public void SetVisualsVisible(bool isVisible) { if (targetRenderers == null) targetRenderers = GetComponentsInChildren(true); foreach (Renderer targetRenderer in targetRenderers) { if (targetRenderer != null) targetRenderer.enabled = isVisible; } } private void ReflectAtMapBounds(ref Vector2 coordinates) { float maximum = MapCoordinateSystem.CoordinateMaximum; if (coordinates.x < 0f || coordinates.x > maximum) { movementDirection.x = -movementDirection.x; coordinates.x = Mathf.Clamp(coordinates.x, 0f, maximum); } if (coordinates.y < 0f || coordinates.y > maximum) { movementDirection.y = -movementDirection.y; coordinates.y = Mathf.Clamp(coordinates.y, 0f, maximum); } } }