Files

158 lines
5.0 KiB
C#

#if UNITY_EDITOR
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
[InitializeOnLoad]
public static class GlobalMonochromeInstaller
{
private const string RendererDataPath = "Assets/Settings/Renderer2D.asset";
private const string GameplayVolumeProfilePath = "Assets/Scenes/gamePlay_gamePlay/gpGV.asset";
private static bool installScheduled;
static GlobalMonochromeInstaller()
{
ScheduleInstall();
}
[MenuItem("Bansonic/Rendering/Install Global Monochrome")]
public static void EnsureInstalledMenu()
{
EnsureInstalled();
}
private static void ScheduleInstall()
{
if (installScheduled)
return;
installScheduled = true;
EditorApplication.delayCall += RunScheduledInstall;
}
private static void RunScheduledInstall()
{
installScheduled = false;
EnsureInstalled();
}
private static void EnsureInstalled()
{
if (EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer)
{
ScheduleInstall();
return;
}
if (IsUnsafeSelectionActive())
{
ScheduleInstall();
return;
}
EnsureRendererFeatureInstalled();
EnsureVolumeOverrideInstalled();
}
private static void EnsureRendererFeatureInstalled()
{
ScriptableRendererData rendererData = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(RendererDataPath);
if (rendererData == null)
return;
if (!rendererData.TryGetRendererFeature<GlobalMonochromeRendererFeature>(out GlobalMonochromeRendererFeature feature))
{
feature = ScriptableObject.CreateInstance<GlobalMonochromeRendererFeature>();
feature.name = "Global Monochrome Renderer Feature";
AssetDatabase.AddObjectToAsset(feature, rendererData);
rendererData.rendererFeatures.Add(feature);
rendererData.SetDirty();
EditorUtility.SetDirty(feature);
EditorUtility.SetDirty(rendererData);
TryValidateRendererFeatures(rendererData);
AssetDatabase.SaveAssets();
AssetDatabase.ImportAsset(RendererDataPath);
return;
}
if (feature.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing)
{
feature.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
rendererData.SetDirty();
EditorUtility.SetDirty(feature);
EditorUtility.SetDirty(rendererData);
AssetDatabase.SaveAssets();
}
}
private static void EnsureVolumeOverrideInstalled()
{
VolumeProfile profile = AssetDatabase.LoadAssetAtPath<VolumeProfile>(GameplayVolumeProfilePath);
if (profile == null)
return;
RemoveNullVolumeComponents(profile);
if (profile.TryGet<GlobalMonochromeVolume>(out _))
return;
GlobalMonochromeVolume component = profile.Add<GlobalMonochromeVolume>(true);
component.active = false;
component.intensity.overrideState = true;
component.intensity.value = 0f;
component.affectSceneView.overrideState = true;
component.affectSceneView.value = false;
EditorUtility.SetDirty(component);
EditorUtility.SetDirty(profile);
AssetDatabase.SaveAssets();
}
private static void RemoveNullVolumeComponents(VolumeProfile profile)
{
SerializedObject serializedObject = new SerializedObject(profile);
SerializedProperty componentsProperty = serializedObject.FindProperty("components");
if (componentsProperty == null || !componentsProperty.isArray)
return;
bool removed = false;
for (int i = componentsProperty.arraySize - 1; i >= 0; i--)
{
SerializedProperty element = componentsProperty.GetArrayElementAtIndex(i);
if (element.objectReferenceValue != null)
continue;
componentsProperty.DeleteArrayElementAtIndex(i);
removed = true;
}
if (!removed)
return;
serializedObject.ApplyModifiedPropertiesWithoutUndo();
EditorUtility.SetDirty(profile);
AssetDatabase.SaveAssets();
}
private static void TryValidateRendererFeatures(ScriptableRendererData rendererData)
{
MethodInfo validateMethod = typeof(ScriptableRendererData).GetMethod("ValidateRendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
validateMethod?.Invoke(rendererData, null);
}
private static bool IsUnsafeSelectionActive()
{
Object activeObject = Selection.activeObject;
if (activeObject is VolumeProfile || activeObject is Volume)
return true;
GameObject activeGameObject = Selection.activeGameObject;
if (activeGameObject == null)
return false;
return activeGameObject.TryGetComponent<Volume>(out _);
}
}
#endif