Firstborn/Library/PackageCache/com.unity.cinemachine@2.8.9/Editor/PostProcessing/CinemachinePostProcessingEd...
Schaken-Mods b486678290 Library -Artifacts
Library -Artifacts
2023-03-28 12:24:16 -05:00

215 lines
8.9 KiB
C#

#if CINEMACHINE_POST_PROCESSING_V2
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering.PostProcessing;
using UnityEditor.Rendering.PostProcessing;
using System.Collections.Generic;
#endif
namespace Cinemachine.PostFX.Editor
{
#if CINEMACHINE_POST_PROCESSING_V2
[CustomEditor(typeof(CinemachinePostProcessing))]
public sealed class CinemachinePostProcessingEditor : Cinemachine.Editor.BaseEditor<CinemachinePostProcessing>
{
SerializedProperty m_Profile;
SerializedProperty m_FocusTracking;
EffectListEditor m_EffectList;
GUIContent m_ProfileLabel;
void OnEnable()
{
Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(
Cinemachine.Editor.ScriptableObjectUtility.CinemachineRealativeInstallPath
+ "/Editor/EditorResources/PostProcessLayer.png");
m_ProfileLabel = new GUIContent("Profile", texture, "A reference to a profile asset");
m_FocusTracking = FindProperty(x => x.m_FocusTracking);
m_Profile = FindProperty(x => x.m_Profile);
m_EffectList = new EffectListEditor(this);
RefreshEffectListEditor(Target.m_Profile);
}
void OnDisable()
{
if (m_EffectList != null)
m_EffectList.Clear();
}
void RefreshEffectListEditor(PostProcessProfile asset)
{
if (m_EffectList == null)
m_EffectList = new EffectListEditor(this);
m_EffectList.Clear();
if (asset != null)
m_EffectList.Init(asset, new SerializedObject(asset));
}
/// <summary>Get the property names to exclude in the inspector.</summary>
/// <param name="excluded">Add the names to this list</param>
protected override void GetExcludedPropertiesInInspector(List<string> excluded)
{
base.GetExcludedPropertiesInInspector(excluded);
var mode = (CinemachinePostProcessing.FocusTrackingMode)m_FocusTracking.intValue;
if (mode != CinemachinePostProcessing.FocusTrackingMode.CustomTarget)
excluded.Add(FieldPath(x => x.m_FocusTarget));
if (mode == CinemachinePostProcessing.FocusTrackingMode.None)
excluded.Add(FieldPath(x => x.m_FocusOffset));
excluded.Add(FieldPath(x => x.m_Profile));
}
public override void OnInspectorGUI()
{
BeginInspector();
DrawRemainingPropertiesInInspector();
var focusMode = (CinemachinePostProcessing.FocusTrackingMode)m_FocusTracking.intValue;
if (focusMode != CinemachinePostProcessing.FocusTrackingMode.None)
{
bool valid = false;
DepthOfField dof;
if (Target.m_Profile != null && Target.m_Profile.TryGetSettings(out dof))
valid = dof.enabled && dof.active && dof.focusDistance.overrideState;
if (!valid)
EditorGUILayout.HelpBox(
"Focus Tracking requires an active DepthOfField/FocusDistance effect in the profile",
MessageType.Warning);
}
EditorGUI.BeginChangeCheck();
DrawProfileInspectorGUI();
if (EditorGUI.EndChangeCheck())
{
Target.InvalidateCachedProfile();
serializedObject.ApplyModifiedProperties();
}
}
void DrawProfileInspectorGUI()
{
EditorGUILayout.Space();
bool assetHasChanged = false;
bool showCopy = m_Profile.objectReferenceValue != null;
// The layout system sort of break alignement when mixing inspector fields with custom
// layouted fields, do the layout manually instead
int buttonWidth = showCopy ? 45 : 60;
float indentOffset = EditorGUI.indentLevel * 15f;
var lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
var labelRect = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
var fieldRect = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth * (showCopy ? 2 : 1), lineRect.height);
var buttonNewRect = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);
var buttonCopyRect = new Rect(buttonNewRect.xMax, lineRect.y, buttonWidth, lineRect.height);
EditorGUI.PrefixLabel(labelRect, m_ProfileLabel);
using (var scope = new EditorGUI.ChangeCheckScope())
{
m_Profile.objectReferenceValue
= (PostProcessProfile)EditorGUI.ObjectField(
fieldRect, m_Profile.objectReferenceValue, typeof(PostProcessProfile), false);
assetHasChanged = scope.changed;
}
if (GUI.Button(
buttonNewRect,
EditorUtilities.GetContent("New|Create a new profile."),
showCopy ? EditorStyles.miniButtonLeft : EditorStyles.miniButton))
{
// By default, try to put assets in a folder next to the currently active
// scene file. If the user isn't a scene, put them in root instead.
var targetName = Target.name;
var scene = Target.gameObject.scene;
var asset = CreatePostProcessProfile(scene, targetName);
m_Profile.objectReferenceValue = asset;
assetHasChanged = true;
}
if (showCopy && GUI.Button(
buttonCopyRect,
EditorUtilities.GetContent("Clone|Create a new profile and copy the content of the currently assigned profile."),
EditorStyles.miniButtonRight))
{
// Duplicate the currently assigned profile and save it as a new profile
var origin = (PostProcessProfile)m_Profile.objectReferenceValue;
var path = AssetDatabase.GetAssetPath(origin);
path = AssetDatabase.GenerateUniqueAssetPath(path);
var asset = Instantiate(origin);
asset.settings.Clear();
AssetDatabase.CreateAsset(asset, path);
foreach (var item in origin.settings)
{
var itemCopy = Instantiate(item);
itemCopy.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy;
itemCopy.name = item.name;
asset.settings.Add(itemCopy);
AssetDatabase.AddObjectToAsset(itemCopy, asset);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
m_Profile.objectReferenceValue = asset;
assetHasChanged = true;
}
if (m_Profile.objectReferenceValue == null)
{
if (assetHasChanged && m_EffectList != null)
m_EffectList.Clear(); // Asset wasn't null before, do some cleanup
EditorGUILayout.HelpBox(
"Assign an existing Post-process Profile by choosing an asset, or create a new one by "
+ "clicking the \"New\" button.\nNew assets are automatically put in a folder next "
+ "to your scene file. If your scene hasn't been saved yet they will be created "
+ "at the root of the Assets folder.",
MessageType.Info);
}
else
{
if (assetHasChanged)
RefreshEffectListEditor((PostProcessProfile)m_Profile.objectReferenceValue);
if (m_EffectList != null)
m_EffectList.OnGUI();
}
}
// Copied from UnityEditor.Rendering.PostProcessing.ProfileFactory.CreatePostProcessProfile() because it's internal
static PostProcessProfile CreatePostProcessProfile(UnityEngine.SceneManagement.Scene scene, string targetName)
{
var path = string.Empty;
if (string.IsNullOrEmpty(scene.path))
{
path = "Assets/";
}
else
{
var scenePath = System.IO.Path.GetDirectoryName(scene.path);
var extPath = scene.name + "_Profiles";
var profilePath = scenePath + "/" + extPath;
if (!AssetDatabase.IsValidFolder(profilePath))
AssetDatabase.CreateFolder(scenePath, extPath);
path = profilePath + "/";
}
path += targetName + " Profile.asset";
path = AssetDatabase.GenerateUniqueAssetPath(path);
var profile = ScriptableObject.CreateInstance<PostProcessProfile>();
AssetDatabase.CreateAsset(profile, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return profile;
}
}
#endif
}