using UnityEngine; using TD.Core; #if UNITY_EDITOR using UnityEditor; #endif namespace TD.Levels { /// /// Authoring volume marking the win-condition target. Enemies that reach a goal volume reduce /// the shared player life pool. Goal tiles are in the /// baked grid but remain walkable so enemies can enter them. /// /// /// Goals have no ownership — they are shared across all players. Multiple goal volumes are /// allowed; the designer specifies the expected count via /// and the bake validates the count matches. /// /// Final defenders are identified by their player zone being 4-adjacent to a goal volume's /// tile coverage; they do not have a LeakExitVolume. /// public class GoalVolume : VolumeBase { [Tooltip("Whether tiles in this volume are buildable. Defaults to Invalid.")] public PlacementValidity placementValidity = PlacementValidity.Invalid; // Goals draw above player zones to be visually anchoring landmarks. Higher alpha than // other volume types (60% per gizmo design). private const float FillYLevel = 0.04f; protected override bool GetAlwaysShowToggle(LevelAuthoring authoring) { return authoring.alwaysShowGoals; } private void OnDrawGizmosSelected() { DrawGizmosCore(); } private void OnDrawGizmos() { if (ShouldDrawAlwaysOn()) { DrawGizmosCore(); } } private void DrawGizmosCore() { Color goalColor = PlayerColors.Goal; DrawTileCoverageFill(goalColor, alpha: 0.60f, yLevel: FillYLevel); DrawRectangularOutline(goalColor, yLevel: FillYLevel); #if UNITY_EDITOR var col = Collider; if (col != null) { Vector3 labelPos = new Vector3(col.bounds.center.x, FillYLevel + 0.1f, col.bounds.center.z); Handles.Label(labelPos, "GOAL"); } #endif } } }