106 lines
3.4 KiB
C#
106 lines
3.4 KiB
C#
using UnityEngine;
|
||
|
||
namespace IndianOceanAssets.Engine2_5D
|
||
{
|
||
/// <summary>
|
||
/// 光源组件(方案B用)—— 挂到任何需要发光的物体上。
|
||
/// 向 LightMaskSystem 注册自己的世界坐标、半径、强度。
|
||
/// 不创建真实的 Point Light,而是由 DarknessOverlay shader 在遮罩层挖洞。
|
||
/// </summary>
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回光源在世界坐标的位置(XZ 平面)
|
||
/// </summary>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 平滑过渡半径(如 Q 键过场时光圈逐渐扩大)
|
||
/// </summary>
|
||
public void LerpRadius(float target, float speed)
|
||
{
|
||
radius = Mathf.Lerp(radius, target, Time.deltaTime * speed);
|
||
radius = Mathf.Max(0.1f, radius);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 平滑过渡强度(如玩家受伤时光变暗、靠近篝火时光变亮)
|
||
/// </summary>
|
||
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);
|
||
}
|
||
}
|
||
} |