2
This commit is contained in:
106
unity/Assets/Light/scripts/LightSource.cs
Normal file
106
unity/Assets/Light/scripts/LightSource.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user