using System;
using System.Collections.Generic;
using UnityEngine;
using BaseGames.Player;
namespace BaseGames.VFX
{
///
/// 形态切换时替换玩家精灵调色板。
/// 通过 Texture2D 查找表(LUT)Shader 实现,不换 Sprite 资产。
/// 挂在玩家 SpriteRenderer 所在 GameObject 上。
/// 由 FormController 在切换形态时调用 ApplyPalette(FormType)。
///
public class PaletteSwapSystem : MonoBehaviour
{
[SerializeField] private SpriteRenderer _renderer;
[SerializeField] private PaletteCatalogSO _catalog;
private static readonly int PaletteTexID = Shader.PropertyToID("_PaletteTex");
private MaterialPropertyBlock _block;
private void Awake()
{
if (_renderer == null)
_renderer = GetComponent();
Debug.Assert(_catalog != null, "[PaletteSwapSystem] _catalog 未赋值,请在 Inspector 中指定 PaletteCatalogSO。", this);
_block = new MaterialPropertyBlock();
}
///
/// 切换到指定形态的调色板。由 FormController.SwitchForm() 调用。
/// 要求 SpriteRenderer 所用 Shader 支持 _PaletteTex(Texture)属性。
///
public void ApplyPalette(FormType form)
{
if (_renderer == null) return;
if (!_catalog.TryGetPalette(form, out var tex)) return;
_renderer.GetPropertyBlock(_block);
_block.SetTexture(PaletteTexID, tex);
_renderer.SetPropertyBlock(_block);
}
}
// ────────────────────────────────────────────────────────────────────────────
// PaletteCatalogSO
// ────────────────────────────────────────────────────────────────────────────
///
/// 形态 → 调色板 LUT(1D Texture2D,256×1 px)映射表。
/// 资产路径:Assets/ScriptableObjects/VFX/VFX_PaletteCatalog.asset
///
[CreateAssetMenu(menuName = "VFX/PaletteCatalog")]
public class PaletteCatalogSO : ScriptableObject
{
[SerializeField] private PaletteEntry[] _entries;
/// 懒初始化字典缓存,将 O(n) 线性查找降为 O(1)。
private Dictionary _cache;
/// 根据形态类型查找对应的调色板 LUT 纹理。
public bool TryGetPalette(FormType form, out Texture2D tex)
{
if (_cache == null)
{
_cache = new Dictionary(_entries?.Length ?? 0);
if (_entries != null)
foreach (var e in _entries)
_cache[e.form] = e.paletteLUT;
}
return _cache.TryGetValue(form, out tex);
}
private void OnValidate() => _cache = null; // 编辑器更改 _entries 后重建缓存
}
/// 单条形态 → LUT 映射数据。
[Serializable]
public struct PaletteEntry
{
public FormType form;
public Texture2D paletteLUT; // 1D 查找表纹理(256×1 px)
}
}