using UnityEngine; namespace IndianOceanAssets.Engine2_5D { /// /// 光源组件(方案B用)—— 挂到任何需要发光的物体上。 /// 向 LightMaskSystem 注册自己的世界坐标、半径、强度。 /// 不创建真实的 Point Light,而是由 DarknessOverlay shader 在遮罩层挖洞。 /// public class LightSource : MonoBehaviour { [Header("光源参数")] [SerializeField] private float radius = 4f; // 光照半径(世界单位) [SerializeField] private float intensity = 1f; // 光照强度 (0~1) [SerializeField] private bool registerOnStart = true; [Header("可选:目标跟随(留空则跟随自身)")] [SerializeField] private Transform followTarget; [Header("闪烁效果")] [SerializeField] private bool enableFlicker = false; [SerializeField] private float flickerSpeed = 5f; [SerializeField] private float flickerAmount = 0.2f; private float baseIntensity; private float noiseSeed; private void Start() { baseIntensity = intensity; noiseSeed = Random.Range(0f, 100f); if (registerOnStart && LightMaskSystem.Instance != null) LightMaskSystem.Instance.RegisterLight(this); } private void Update() { if (enableFlicker) { float noise = Mathf.PerlinNoise(Time.time * flickerSpeed, noiseSeed); intensity = baseIntensity + (noise - 0.5f) * 2f * flickerAmount; intensity = Mathf.Clamp01(intensity); } } /// /// 返回光源在世界坐标的位置(XZ 平面) /// public Vector2 GetWorldPositionXZ() { Transform t = followTarget != null ? followTarget : transform; return new Vector2(t.position.x, t.position.z); } public float Radius => radius; public float Intensity => intensity; public void SetIntensity(float value) { baseIntensity = Mathf.Clamp01(value); intensity = baseIntensity; } public void SetRadius(float value) { radius = Mathf.Max(0.1f, value); } /// /// 平滑过渡半径(如 Q 键过场时光圈逐渐扩大) /// public void LerpRadius(float target, float speed) { radius = Mathf.Lerp(radius, target, Time.deltaTime * speed); radius = Mathf.Max(0.1f, radius); } /// /// 平滑过渡强度(如玩家受伤时光变暗、靠近篝火时光变亮) /// public void LerpIntensity(float target, float speed) { baseIntensity = Mathf.Lerp(baseIntensity, Mathf.Clamp01(target), Time.deltaTime * speed); intensity = baseIntensity; } private void OnEnable() { if (LightMaskSystem.Instance != null) LightMaskSystem.Instance.RegisterLight(this); } private void OnDisable() { if (LightMaskSystem.Instance != null) LightMaskSystem.Instance.UnregisterLight(this); } private void OnDestroy() { if (LightMaskSystem.Instance != null) LightMaskSystem.Instance.UnregisterLight(this); } } }