Major updates to the HUD and selectable objects

This commit is contained in:
Matt F 2026-05-11 23:57:35 -07:00
parent 5bc757b385
commit c100db52e5
23 changed files with 1615 additions and 614 deletions

View file

@ -135,6 +135,56 @@ namespace TD.Gameplay
/// <summary>Ends external drag mode. Normal input handling resumes.</summary>
public void EndDrag() => isExternalDragActive = false;
/// <summary>
/// Computes where the four screen corners project onto the buildable plane and
/// writes them into <paramref name="cornersOut"/> in the order BL, BR, TR, TL.
/// Returns true when every ray hits the plane in front of the camera. When the
/// camera angles above the horizon for one or more corners (rare in our pitch
/// range), those corner(s) fall back to a far point along the ray and the method
/// returns false — the caller may still use the result; the off-plane corners
/// just sit far outside the map. Used by the minimap to draw the viewport
/// trapezoid (the "what the player sees" rectangle).
/// </summary>
public bool TryGetViewportWorldCorners(Vector3[] cornersOut)
{
if (cornersOut == null || cornersOut.Length < 4) return false;
if (cameraChild == null) return false;
// Buildable plane is Y = BUILDABLE_PLANE_Y, normal = up.
var plane = new Plane(Vector3.up,
new Vector3(0f, GridCoordinates.BUILDABLE_PLANE_Y, 0f));
// Screen-space order: BL, BR, TR, TL (origin at bottom-left, Y up).
// Resulting world points form a trapezoid on the buildable plane (camera
// is angled, so the far edge — top of screen — projects wider than the
// near edge — bottom of screen).
float w = Screen.width;
float h = Screen.height;
cornersOut[0] = ProjectScreenToPlane(new Vector2(0f, 0f), plane, out bool a);
cornersOut[1] = ProjectScreenToPlane(new Vector2(w, 0f), plane, out bool b);
cornersOut[2] = ProjectScreenToPlane(new Vector2(w, h ), plane, out bool c);
cornersOut[3] = ProjectScreenToPlane(new Vector2(0f, h ), plane, out bool d);
return a && b && c && d;
}
// Helper: ray from screen point, intersect plane. If it doesn't hit in front of
// the camera (rare — only at horizon-or-above pitches), use a far fallback so
// the caller still gets a usable value.
private Vector3 ProjectScreenToPlane(Vector2 screenPoint, Plane plane, out bool hit)
{
Ray ray = cameraChild.ScreenPointToRay(new Vector3(screenPoint.x, screenPoint.y, 0f));
if (plane.Raycast(ray, out float dist) && dist > 0f)
{
hit = true;
return ray.GetPoint(dist);
}
hit = false;
// Far point along the ray as a graceful fallback. Distance picked large enough
// that the resulting UI coord lands well outside the minimap bounds and gets
// clipped by overflow:hidden.
return ray.GetPoint(1000f);
}
// ----- Lifecycle --------------------------------------------------
private void Start()