using UnityEngine; /// /// 部署格位高亮:拖动卡牌时在目标格位显示一块发光地板。 /// 绿色 = 可以放置;红色 = 该格已被占用 / 不可放置。 /// 全场只需要一个,由 DefenseGameFlowController 在布阵阶段创建。 /// public class DeployHighlight : MonoBehaviour { public static DeployHighlight Instance { get; private set; } private static readonly Color FreeColor = new Color(0.25f, 1f, 0.45f, 0.55f); private static readonly Color BlockedColor = new Color(1f, 0.28f, 0.28f, 0.55f); private GameObject plate; private Material plateMaterial; private int shownCell = -1; /// 高亮当前是否可见。 public bool IsVisible => plate != null && plate.activeSelf; /// 当前显示的是否是"不可放置"(红色)。 public bool IsBlocked { get; private set; } /// 当前高亮所在的格位,-1 表示没有。 public int ShownCell => shownCell; public static DeployHighlight Ensure() { if (Instance != null) return Instance; var go = new GameObject("DeployHighlight"); Instance = go.AddComponent(); Instance.Build(); return Instance; } private void Awake() { if (Instance == null) { Instance = this; Build(); } } private void Build() { if (plate != null) return; plate = GameObject.CreatePrimitive(PrimitiveType.Cube); plate.name = "CellPlate"; plate.transform.SetParent(transform, false); plate.transform.localRotation = Quaternion.identity; plate.transform.localScale = new Vector3(DeployGrid.CellWidth * 0.96f, 0.02f, DeployGrid.CellDepth * 0.96f); // 高亮只是视觉提示,不需要碰撞 var collider = plate.GetComponent(); if (collider != null) { Destroy(collider); } var shader = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); plateMaterial = new Material(shader); plateMaterial.name = "DeployHighlightMat"; plateMaterial.color = FreeColor; var renderer = plate.GetComponent(); renderer.sharedMaterial = plateMaterial; renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; renderer.receiveShadows = false; plate.SetActive(false); } /// 在指定格位显示高亮。blocked = true 显示红色。 public void Show(int cellIndex, bool blocked) { if (plate == null) Build(); if (!DeployGrid.IsValidIndex(cellIndex)) { Hide(); return; } var pos = DeployGrid.CellPosition(cellIndex); plate.transform.position = new Vector3(pos.x, DeployGrid.GridY + 0.05f, pos.z); plateMaterial.color = blocked ? BlockedColor : FreeColor; IsBlocked = blocked; if (shownCell != cellIndex || !plate.activeSelf) { plate.SetActive(true); shownCell = cellIndex; } } public void Hide() { if (plate != null && plate.activeSelf) { plate.SetActive(false); } shownCell = -1; IsBlocked = false; } private void OnDestroy() { if (Instance == this) Instance = null; } }