112 lines
4.2 KiB
C#
112 lines
4.2 KiB
C#
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
/// <summary>
|
||
/// 棋子控件(支持两种接入方式):
|
||
///
|
||
/// 1. 预制体(推荐,拖到 UIChessBoard.prefab_Piece):
|
||
/// 根节点:挂本脚本 + Image(棋子底图,可留空由代码补默认圆)
|
||
/// 可选子物体:TMP 文字(显示汉字,用按类型成品图时会自动隐藏)、
|
||
/// 名为 SelectRing 的 Image(选中描边圈,没有则用底图变色代替)
|
||
///
|
||
/// 2. 不拖预制体:由 UIChessBoard 代码生成默认样式(Image + SelectRing + Label)
|
||
/// </summary>
|
||
public class UIChessPiece : MonoBehaviour
|
||
{
|
||
/// <summary>棋子数据(普通类数据,表现层唯一数据源)</summary>
|
||
public ChessPieceData data;
|
||
|
||
/// <summary>棋子底图(预制体上拖;为空自动 GetComponent)</summary>
|
||
public Image img_Piece;
|
||
|
||
/// <summary>棋子汉字(预制体上拖 TMP 子物体;为空自动查找)</summary>
|
||
public TextMeshProUGUI tmp_Label;
|
||
|
||
/// <summary>选中描边圈(预制体上拖;为空自动找名为 SelectRing 的子物体)</summary>
|
||
public Image img_Select;
|
||
|
||
private Button btn_Click;
|
||
private UIChessBoard ownerBoard;
|
||
private Color originalColor = Color.white;
|
||
private Color selectTint = new Color(1f, 0.84f, 0.31f, 1f);
|
||
|
||
/// <summary>由 UIChessBoard 生成时调用</summary>
|
||
public void Init(UIChessBoard board, ChessPieceData pieceData)
|
||
{
|
||
ownerBoard = board;
|
||
data = pieceData;
|
||
|
||
// ---- 底图 ----
|
||
if (img_Piece == null) img_Piece = GetComponent<Image>();
|
||
if (img_Piece != null)
|
||
{
|
||
img_Piece.raycastTarget = true;
|
||
originalColor = img_Piece.color;
|
||
selectTint = Color.Lerp(originalColor, new Color(1f, 0.85f, 0.3f), 0.5f);
|
||
|
||
// 图片优先级:按类型的成品图 > 通用底图 > 预制体自带图 > 代码生成圆
|
||
Sprite typeSprite = board.GetTypeSprite(data.camp, data.pieceType);
|
||
if (typeSprite != null) img_Piece.sprite = typeSprite;
|
||
else if (board.sprite_PieceBg != null) img_Piece.sprite = board.sprite_PieceBg;
|
||
else if (img_Piece.sprite == null) img_Piece.sprite = ChessArtFactory.GetCircleSprite();
|
||
}
|
||
|
||
// ---- 汉字 ----
|
||
if (tmp_Label == null) tmp_Label = GetComponentInChildren<TextMeshProUGUI>(true);
|
||
if (tmp_Label != null)
|
||
{
|
||
if (board.GetTypeSprite(data.camp, data.pieceType) != null)
|
||
{
|
||
// 用了按类型的成品图(图里已带字)→ 隐藏文字
|
||
tmp_Label.gameObject.SetActive(false);
|
||
}
|
||
else
|
||
{
|
||
tmp_Label.gameObject.SetActive(true);
|
||
tmp_Label.text = data.displayName;
|
||
tmp_Label.color = board.GetTextColor(data.camp);
|
||
if (tmp_Label.font == null && board.ResolvedFont != null)
|
||
tmp_Label.font = board.ResolvedFont;
|
||
}
|
||
tmp_Label.raycastTarget = false;
|
||
}
|
||
|
||
// ---- 选中描边 ----
|
||
if (img_Select == null)
|
||
{
|
||
var t = transform.Find("SelectRing");
|
||
if (t != null) img_Select = t.GetComponent<Image>();
|
||
}
|
||
if (img_Select != null)
|
||
{
|
||
img_Select.raycastTarget = false;
|
||
img_Select.gameObject.SetActive(false);
|
||
}
|
||
|
||
// ---- 按钮 ----
|
||
btn_Click = GetComponent<Button>();
|
||
if (btn_Click == null) btn_Click = gameObject.AddComponent<Button>();
|
||
btn_Click.targetGraphic = img_Piece;
|
||
btn_Click.onClick.AddListener(() => ownerBoard.OnPieceClicked(this));
|
||
}
|
||
|
||
/// <summary>选中/取消选中(有 SelectRing 显示圈,没有则底图变色)</summary>
|
||
public void SetSelected(bool value)
|
||
{
|
||
if (img_Select != null)
|
||
{
|
||
img_Select.gameObject.SetActive(value);
|
||
if (img_Piece != null) img_Piece.color = originalColor;
|
||
return;
|
||
}
|
||
if (img_Piece != null) img_Piece.color = value ? selectTint : originalColor;
|
||
}
|
||
|
||
/// <summary>禁用/启用点击</summary>
|
||
public void SetInteractable(bool value)
|
||
{
|
||
if (btn_Click != null) btn_Click.interactable = value;
|
||
}
|
||
}
|