using System.Collections; using UnityEngine; using UnityEngine.Events; [DisallowMultipleComponent] public sealed class MapImpactMarkerView : MonoBehaviour { [SerializeField] private MapCoordinateSystem coordinateSystem; [SerializeField, Min(0.01f)] private float markerLength = 0.35f; [SerializeField, Min(0.005f)] private float markerThickness = 0.035f; [SerializeField, Min(0f)] private float surfaceOffset = 0.025f; [SerializeField, Min(0.1f)] private float lifetime = 5f; [SerializeField] private Color hitColor = new(1f, 0.1f, 0.05f, 1f); [SerializeField] private Color missColor = new(1f, 0.75f, 0f, 1f); [SerializeField] private bool showMisses = true; [SerializeField] private UnityEvent hitMarked; [SerializeField] private UnityEvent missMarked; public void Configure(MapCoordinateSystem coordinates) => coordinateSystem = coordinates; public void Show(MapShotResultState result) { if (coordinateSystem == null || (!result.Hit && !showMisses)) return; CreateMarker(result.Coordinates, result.Hit ? hitColor : missColor); if (result.Hit) hitMarked?.Invoke(); else missMarked?.Invoke(); } private void CreateMarker(Vector2 coordinates, Color color) { Vector3 horizontal = coordinateSystem.BottomRight.position - coordinateSystem.BottomLeft.position; Vector3 vertical = coordinateSystem.TopLeft.position - coordinateSystem.BottomLeft.position; Vector3 normal = Vector3.Cross(horizontal, vertical).normalized; if (normal.sqrMagnitude < 0.5f) normal = transform.forward; GameObject marker = new($"Impact {coordinates.x:0.0}, {coordinates.y:0.0}"); marker.transform.SetParent(transform, true); marker.transform.SetPositionAndRotation( coordinateSystem.CoordinatesToWorldPosition(coordinates) + normal * surfaceOffset, Quaternion.LookRotation(normal, vertical.normalized)); CreateBar(marker.transform, 45f, color); CreateBar(marker.transform, -45f, color); StartCoroutine(DestroyAfterLifetime(marker)); } private void CreateBar(Transform parent, float angle, Color color) { GameObject bar = GameObject.CreatePrimitive(PrimitiveType.Cube); bar.name = "Marker Bar"; bar.transform.SetParent(parent, false); bar.transform.localRotation = Quaternion.Euler(0f, 0f, angle); bar.transform.localScale = new Vector3( markerLength, markerThickness, markerThickness); Collider collider = bar.GetComponent(); if (collider != null) Destroy(collider); Renderer renderer = bar.GetComponent(); if (renderer != null) renderer.material.color = color; } private IEnumerator DestroyAfterLifetime(GameObject marker) { yield return new WaitForSeconds(lifetime); if (marker != null) Destroy(marker); } }