using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; namespace GraphicsCat { [ExecuteAlways] public class ShadowDistance : MonoBehaviour { public enum Mode { Static, Dynamic } public Mode mode = Mode.Static; [EnableIf(nameof(mode), CompareFunction.Equal, Mode.Static)] [Range(1f, 100f)] public float staticDistance = 10f; [InspectorDisplayName("Dynamic Distance Target")] [EnableIf(nameof(mode), CompareFunction.Equal, Mode.Dynamic)] public GameObject dynamicDistanceTarget; [InspectorDisplayName("Dynamic Distance Offset")] [EnableIf(nameof(mode), CompareFunction.Equal, Mode.Dynamic)] public float dynamicDistanceOffset = 0f; float m_TargetHalfSize = 0; void OnEnable() { UpdateShadowDistance(); UpdateDynamicDistanceTargetHalfSize(); } void Update() { UpdateShadowDistance(); } void OnValidate() { UpdateShadowDistance(); UpdateDynamicDistanceTargetHalfSize(); } void UpdateShadowDistance() { if (mode == Mode.Static) SetShadowDistance(staticDistance); else UpdateShadowDistanceByLookTarget(); } void UpdateShadowDistanceByLookTarget() { var target = dynamicDistanceTarget; if (target == null) target = gameObject; Camera mainCamera = Camera.main; if (mainCamera == null) return; var targetDistance = (target.transform.position - mainCamera.transform.position).magnitude; var shadowDistance = targetDistance + m_TargetHalfSize + dynamicDistanceOffset; SetShadowDistance(shadowDistance); } float GetShadowDistance() { var uprAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset; if (uprAsset != null) return uprAsset.shadowDistance; else return QualitySettings.shadowDistance; } void SetShadowDistance(float val) { var urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset; if (urpAsset != null) urpAsset.shadowDistance = val; else QualitySettings.shadowDistance = val; } void UpdateDynamicDistanceTargetHalfSize() { var bounds = BoundsUtils.GetHierarchyBounds(dynamicDistanceTarget); m_TargetHalfSize = bounds.extents.magnitude; } } }