using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using BaseGames.Core.Events;
namespace BaseGames.VFX
{
///
/// 区域进出时平滑切换 Global Light 2D 颜色和强度。
/// 挂在 Persistent 场景 [Lighting] GameObject 上,监听 OnRegionEntered 事件频道。
///
public class RegionLightController : MonoBehaviour
{
[SerializeField] private Light2D _globalLight;
[SerializeField] private RegionLightCatalogSO _catalog;
[SerializeField] private StringEventChannelSO _onRegionEntered;
[SerializeField] private float _transitionDuration = 1.5f;
private Coroutine _colorCoroutine;
private Coroutine _intensityCoroutine;
private readonly CompositeDisposable _subs = new();
private void Awake()
{
Debug.Assert(_catalog != null, "[RegionLightController] _catalog 未赋值,请在 Inspector 中指定 RegionLightCatalogSO。", this);
Debug.Assert(_globalLight != null, "[RegionLightController] _globalLight 未赋值,请在 Inspector 中绑定 Light2D。", this);
}
private void OnEnable()
{
_onRegionEntered?.Subscribe(OnRegionEntered).AddTo(_subs);
}
private void OnDisable()
{
_subs.Clear();
}
private void OnRegionEntered(string regionId)
{
if (!_catalog.TryGet(regionId, out var config)) return;
if (_colorCoroutine != null) StopCoroutine(_colorCoroutine);
if (_intensityCoroutine != null) StopCoroutine(_intensityCoroutine);
_colorCoroutine = StartCoroutine(TweenColor(_globalLight.color, config.Color, _transitionDuration));
_intensityCoroutine = StartCoroutine(TweenIntensity(_globalLight.intensity, config.Intensity, _transitionDuration));
}
// ── Coroutine helpers ────────────────────────────────────────────────────
private IEnumerator TweenColor(Color from, Color to, float duration)
{
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
_globalLight.color = Color.Lerp(from, to, Mathf.Clamp01(elapsed / duration));
yield return null;
}
_globalLight.color = to;
_colorCoroutine = null;
}
private IEnumerator TweenIntensity(float from, float to, float duration)
{
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
_globalLight.intensity = Mathf.Lerp(from, to, Mathf.Clamp01(elapsed / duration));
yield return null;
}
_globalLight.intensity = to;
_intensityCoroutine = null;
}
}
// ────────────────────────────────────────────────────────────────────────────
// RegionLightCatalogSO
// ────────────────────────────────────────────────────────────────────────────
///
/// 区域 ID → Global Light 2D 颜色 + 强度映射表。
/// 资产路径:Assets/ScriptableObjects/VFX/VFX_RegionLightCatalog.asset
///
[CreateAssetMenu(menuName = "VFX/RegionLightCatalog")]
public class RegionLightCatalogSO : ScriptableObject
{
[Serializable]
public struct RegionLightConfig
{
public string regionId;
public Color Color;
[Range(0f, 1f)] public float Intensity;
}
[SerializeField] private RegionLightConfig[] _entries;
/// 根据 regionId 查找对应的灯光配置。
public bool TryGet(string regionId, out RegionLightConfig cfg)
{
if (_entries != null)
{
foreach (var e in _entries)
{
if (e.regionId == regionId) { cfg = e; return true; }
}
}
cfg = default;
return false;
}
}
}