多轮审查和修复
This commit is contained in:
114
Assets/Scripts/VFX/RegionLightController.cs
Normal file
114
Assets/Scripts/VFX/RegionLightController.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using BaseGames.Core.Events;
|
||||
|
||||
namespace BaseGames.VFX
|
||||
{
|
||||
/// <summary>
|
||||
/// 区域进出时平滑切换 Global Light 2D 颜色和强度。
|
||||
/// 挂在 Persistent 场景 [Lighting] GameObject 上,监听 OnRegionEntered 事件频道。
|
||||
/// </summary>
|
||||
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
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 区域 ID → Global Light 2D 颜色 + 强度映射表。
|
||||
/// 资产路径:Assets/ScriptableObjects/VFX/VFX_RegionLightCatalog.asset
|
||||
/// </summary>
|
||||
[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;
|
||||
|
||||
/// <summary>根据 regionId 查找对应的灯光配置。</summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user