77 lines
3.0 KiB
C#
77 lines
3.0 KiB
C#
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<Collider>();
|
|
if (collider != null)
|
|
Destroy(collider);
|
|
Renderer renderer = bar.GetComponent<Renderer>();
|
|
if (renderer != null)
|
|
renderer.material.color = color;
|
|
}
|
|
|
|
private IEnumerator DestroyAfterLifetime(GameObject marker)
|
|
{
|
|
yield return new WaitForSeconds(lifetime);
|
|
if (marker != null)
|
|
Destroy(marker);
|
|
}
|
|
}
|