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;
}
}