76 lines
2.6 KiB
C#
76 lines
2.6 KiB
C#
|
using Games.Events;
|
|||
|
using Games.Scene;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 设置当前场景方向光到全局参数上
|
|||
|
/// </summary>
|
|||
|
// 注:因为美术效果很多时候阴影方向和镜面反射所需光线方向冲突,因此修改组件为可自由旋转
|
|||
|
// 注:现在这个工具也用于处理平行光动态阴影开关
|
|||
|
public class DirectionalLightSetter : MonoBehaviour
|
|||
|
{
|
|||
|
private const string _dirPropertyName = "_DirectionalLight";
|
|||
|
// 镜面反射单独使用一个方向
|
|||
|
private const string _specularPropertyName = "_SpecularLight";
|
|||
|
private const string _colorPropertyName = "_DirectionalLightColor";
|
|||
|
private const string _attenPropertyName = "_DirectionalLightAtten";
|
|||
|
// 欧拉角度表示的镜面反射方向
|
|||
|
public Quaternion specularRotation = Quaternion.identity;
|
|||
|
|
|||
|
private Light _lightComponent;
|
|||
|
|
|||
|
private void Start()
|
|||
|
{
|
|||
|
_lightComponent = GetComponent<Light>();
|
|||
|
PlayerPreferenceData.SystemQualityDymShadow.onSettingUpdate += OnDynamicShadowToggle;
|
|||
|
OnDynamicShadowToggle(PlayerPreferenceData.SystemQualityDymShadow);
|
|||
|
EventDispatcher.Instance.Add(Games.Events.EventId.PostMainCameraMove, OnCameraMove);
|
|||
|
SetLight();
|
|||
|
}
|
|||
|
|
|||
|
private void OnDestroy()
|
|||
|
{
|
|||
|
if (!GameManager.applicationQuit)
|
|||
|
{
|
|||
|
PlayerPreferenceData.SystemQualityDymShadow.onSettingUpdate -= OnDynamicShadowToggle;
|
|||
|
EventDispatcher.Instance.Remove(Games.Events.EventId.PostMainCameraMove, OnCameraMove);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void OnDynamicShadowToggle(bool isOn)
|
|||
|
{
|
|||
|
_lightComponent.enabled = isOn;
|
|||
|
}
|
|||
|
|
|||
|
public void SetLight(Light light)
|
|||
|
{
|
|||
|
Shader.SetGlobalVector(_dirPropertyName, transform.rotation * Vector3.back);
|
|||
|
Shader.SetGlobalColor(_colorPropertyName, light.color);
|
|||
|
Shader.SetGlobalFloat(_attenPropertyName, light.intensity);
|
|||
|
Shader.SetGlobalVector(_specularPropertyName, specularRotation * Vector3.back);
|
|||
|
}
|
|||
|
|
|||
|
public void SetLight()
|
|||
|
{
|
|||
|
SetLight(_lightComponent);
|
|||
|
}
|
|||
|
|
|||
|
private float? _baseYaw;
|
|||
|
private float _lastYaw;
|
|||
|
private void OnCameraMove(object args)
|
|||
|
{
|
|||
|
if (_baseYaw == null)
|
|||
|
{
|
|||
|
_lastYaw = SceneLogic.CameraController.Yaw;
|
|||
|
_baseYaw = _lastYaw;
|
|||
|
}
|
|||
|
else if (_lastYaw != SceneLogic.CameraController.Yaw)
|
|||
|
{
|
|||
|
var yaw = SceneLogic.CameraController.Yaw;
|
|||
|
var deltaYaw = yaw - _baseYaw.Value;
|
|||
|
_lastYaw = yaw;
|
|||
|
var rotation = Quaternion.Euler(0f, deltaYaw, 0f) * specularRotation;
|
|||
|
Shader.SetGlobalVector(_specularPropertyName, rotation * Vector3.back);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|