using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
namespace Beautify.Universal {
public delegate float OnBeforeFocusEvent(float currentFocusDistance);
public delegate void OnCameraBeforeFocusEvent(Camera camera, ref float currentFocusDistance);
public delegate void OnCameraBeforeAutofocusEvent(Camera camera, ref Transform target);
[ExecuteAlways]
public class BeautifySettings : MonoBehaviour {
public Transform sun;
public Transform depthOfFieldTarget;
[Tooltip("Enable to use Focus Position instead of volume setting")]
public bool depthOfFieldFocusPositionEnabled;
[Tooltip("World position to focus on when FollowPosition mode is selected")]
public Vector3 depthOfFieldFocusPosition;
public OnBeforeFocusEvent OnBeforeFocus;
public OnCameraBeforeFocusEvent OnCameraBeforeFocus;
public OnCameraBeforeAutofocusEvent OnCameraBeforeAutofocus;
public static float depthOfFieldCurrentFocalPointDistance;
public static int bloomExcludeMask;
public static int anamorphicFlaresExcludeMask;
public static int sharpenExclusionMask;
public static bool dofTransparentSupport;
public static int dofTransparentLayerMask;
public static bool dofTransparentDoubleSided;
public static bool dofAlphaTestSupport;
public static int dofAlphaTestLayerMask;
public static bool dofAlphaTestDoubleSided;
public static bool outlineDepthPrepass;
public static bool outlineUseObjectId;
public static int outlineLayerMask;
public static float outlineLayerCutOff;
public static bool outlineDepthPrepassUseOptimizedShader;
internal static bool _refreshAlphaClipRenderers;
static BeautifySettings _instance;
static Volume _beautifyVolume;
static Beautify _beautify;
///
/// Forces a reset of the internal cached settings of Beautify. Call this method if Beautify settings are not resetted when switching scenes.
///
public static void UnloadBeautify() {
_instance = null;
_beautifyVolume = null;
_beautify = null;
}
///
/// Returns a reference to the Beautify Settings component attached to the Post Processing Layer or camera
///
/// The instance.
public static BeautifySettings instance {
get {
if (_instance != null) return _instance;
// Fallback: auto-create BeautifySettings on the Beautify volume if it doesn't exist
_beautifyVolume = FindBeautifyVolume();
if (_beautifyVolume == null) {
return null;
}
GameObject go = _beautifyVolume.gameObject;
_instance = go.GetComponent();
if (_instance == null) {
_instance = go.AddComponent();
}
return _instance;
}
}
static Volume FindBeautifyVolume() {
#if UNITY_2023_1_OR_NEWER
Volume[] vols = FindObjectsByType(FindObjectsSortMode.None);
#else
Volume[] vols = FindObjectsOfType();
#endif
foreach (Volume volume in vols) {
if (volume.sharedProfile != null && volume.sharedProfile.Has()) {
_beautifyVolume = volume;
return volume;
}
}
return null;
}
///
/// Returns a reference to the settings of Beautify in the Post Processing Profile
///
/// The shared settings.
public static Beautify sharedSettings {
get {
if (_beautify != null) return _beautify;
if (_beautifyVolume == null) FindBeautifyVolume();
if (_beautifyVolume == null) return null;
bool foundEffectSettings = _beautifyVolume.sharedProfile.TryGet(out _beautify);
if (!foundEffectSettings) {
Debug.Log("Cant load Beautify settings");
return null;
}
return _beautify;
}
}
///
/// Returns the profile of the volume in the scene where Beautify has been found
///
public static VolumeProfile currentProfile {
get {
if (_beautifyVolume == null) {
FindBeautifyVolume();
}
if (_beautifyVolume == null) return null;
return _beautifyVolume.sharedProfile;
}
}
///
/// Returns a copy of the settings of Beautify in the Post Processing Profile
///
/// The settings.
public static Beautify settings {
get {
if (_beautify != null) return _beautify;
if (_beautifyVolume == null) FindBeautifyVolume();
if (_beautifyVolume == null) return null;
bool foundEffectSettings = _beautifyVolume.profile.TryGet(out _beautify);
if (!foundEffectSettings) {
Debug.Log("Cant load Beautify settings");
return null;
}
return _beautify;
}
}
public static void Blink(float duration, float maxValue = 1) {
if (duration <= 0)
return;
BeautifySettings i = instance;
if (i == null) return;
i.StartCoroutine(i.DoBlink(duration, maxValue));
}
IEnumerator DoBlink(float duration, float maxValue) {
Beautify beautify = settings;
if (beautify == null) yield break;
float start = Time.time;
WaitForEndOfFrame w = new WaitForEndOfFrame();
beautify.vignettingBlink.overrideState = true;
float t;
// Close
do {
t = (Time.time - start) / duration;
if (t > 1f)
t = 1f;
float easeOut = t * (2f - t);
beautify.vignettingBlink.value = easeOut * maxValue;
yield return w;
} while (t < 1f);
// Open
start = Time.time;
do {
t = (Time.time - start) / duration;
if (t > 1f)
t = 1f;
float easeIn = t * t;
beautify.vignettingBlink.value = (1f - easeIn) * maxValue;
yield return w;
} while (t < 1f);
beautify.vignettingBlink.overrideState = false;
}
void OnEnable() {
if (_instance == null) {
_instance = this;
}
#if UNITY_EDITOR
if (!Application.isPlaying) {
BeautifyRendererFeature.StripBeautifyFeatures();
}
#endif
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}
private void OnDisable() {
if (_instance == this) {
_instance = null;
}
SceneManager.sceneLoaded -= SceneManager_sceneLoaded;
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1) {
UnloadBeautify();
}
///
/// Updates the list of alpha clip renderers
///
public static void UpdateAlphaClipRenderers() {
_refreshAlphaClipRenderers = true;
}
}
}