86 lines
3.4 KiB
C#
86 lines
3.4 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using BaseGames.Player;
|
||
|
||
namespace BaseGames.VFX
|
||
{
|
||
/// <summary>
|
||
/// 形态切换时替换玩家精灵调色板。
|
||
/// 通过 Texture2D 查找表(LUT)Shader 实现,不换 Sprite 资产。
|
||
/// 挂在玩家 SpriteRenderer 所在 GameObject 上。
|
||
/// 由 FormController 在切换形态时调用 ApplyPalette(FormType)。
|
||
/// </summary>
|
||
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<SpriteRenderer>();
|
||
Debug.Assert(_catalog != null, "[PaletteSwapSystem] _catalog 未赋值,请在 Inspector 中指定 PaletteCatalogSO。", this);
|
||
_block = new MaterialPropertyBlock();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 切换到指定形态的调色板。由 FormController.SwitchForm() 调用。
|
||
/// 要求 SpriteRenderer 所用 Shader 支持 _PaletteTex(Texture)属性。
|
||
/// </summary>
|
||
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
|
||
// ────────────────────────────────────────────────────────────────────────────
|
||
|
||
/// <summary>
|
||
/// 形态 → 调色板 LUT(1D Texture2D,256×1 px)映射表。
|
||
/// 资产路径:Assets/ScriptableObjects/VFX/VFX_PaletteCatalog.asset
|
||
/// </summary>
|
||
[CreateAssetMenu(menuName = "VFX/PaletteCatalog")]
|
||
public class PaletteCatalogSO : ScriptableObject
|
||
{
|
||
[SerializeField] private PaletteEntry[] _entries;
|
||
|
||
/// <summary>懒初始化字典缓存,将 O(n) 线性查找降为 O(1)。</summary>
|
||
private Dictionary<FormType, Texture2D> _cache;
|
||
|
||
/// <summary>根据形态类型查找对应的调色板 LUT 纹理。</summary>
|
||
public bool TryGetPalette(FormType form, out Texture2D tex)
|
||
{
|
||
if (_cache == null)
|
||
{
|
||
_cache = new Dictionary<FormType, Texture2D>(_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 后重建缓存
|
||
}
|
||
|
||
/// <summary>单条形态 → LUT 映射数据。</summary>
|
||
[Serializable]
|
||
public struct PaletteEntry
|
||
{
|
||
public FormType form;
|
||
public Texture2D paletteLUT; // 1D 查找表纹理(256×1 px)
|
||
}
|
||
}
|