Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit e751d1a

Browse files
authored
Merge pull request #548 from Unity-Technologies/p530-cherry-pick
Cherry picking #530
2 parents 04caaaa + 33685c0 commit e751d1a

File tree

6 files changed

+79
-30
lines changed

6 files changed

+79
-30
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this package will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [Indev]
8+
9+
### Fixed
10+
- On large scenes, the first object you'd add to a profile could throw a `NullReferenceException`. ([#530](https://github.com/Unity-Technologies/PostProcessing/pull/530))
11+
12+
### Changed
13+
- Minor scripting API improvements. ([#530](https://github.com/Unity-Technologies/PostProcessing/pull/530))
14+
- Script-instantiated profiles in volumes are now properly supported in the inspector. ([#530](https://github.com/Unity-Technologies/PostProcessing/pull/530))
15+
716
## [2.0.5-preview]
817

918
### Fixed

PostProcessing/Editor/EffectListEditor.cs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ namespace UnityEditor.Rendering.PostProcessing
99
{
1010
public sealed class EffectListEditor
1111
{
12+
public PostProcessProfile asset { get; private set; }
1213
Editor m_BaseEditor;
1314

14-
PostProcessProfile m_Asset;
1515
SerializedObject m_SerializedObject;
1616
SerializedProperty m_SettingsProperty;
1717

@@ -29,7 +29,7 @@ public void Init(PostProcessProfile asset, SerializedObject serializedObject)
2929
Assert.IsNotNull(asset);
3030
Assert.IsNotNull(serializedObject);
3131

32-
m_Asset = asset;
32+
this.asset = asset;
3333
m_SerializedObject = serializedObject;
3434
m_SettingsProperty = serializedObject.FindProperty("settings");
3535
Assert.IsNotNull(m_SettingsProperty);
@@ -53,16 +53,16 @@ public void Init(PostProcessProfile asset, SerializedObject serializedObject)
5353
}
5454

5555
// Create editors for existing settings
56-
for (int i = 0; i < m_Asset.settings.Count; i++)
57-
CreateEditor(m_Asset.settings[i], m_SettingsProperty.GetArrayElementAtIndex(i));
56+
for (int i = 0; i < this.asset.settings.Count; i++)
57+
CreateEditor(this.asset.settings[i], m_SettingsProperty.GetArrayElementAtIndex(i));
5858

5959
// Keep track of undo/redo to redraw the inspector when that happens
6060
Undo.undoRedoPerformed += OnUndoRedoPerformed;
6161
}
6262

6363
void OnUndoRedoPerformed()
6464
{
65-
m_Asset.isDirty = true;
65+
asset.isDirty = true;
6666

6767
// Dumb hack to make sure the serialized object is up to date on undo (else there'll be
6868
// a state mismatch when this class is used in a GameObject inspector).
@@ -104,8 +104,8 @@ void RefreshEditors()
104104
m_Editors.Clear();
105105

106106
// Recreate editors for existing settings, if any
107-
for (int i = 0; i < m_Asset.settings.Count; i++)
108-
CreateEditor(m_Asset.settings[i], m_SettingsProperty.GetArrayElementAtIndex(i));
107+
for (int i = 0; i < asset.settings.Count; i++)
108+
CreateEditor(asset.settings[i], m_SettingsProperty.GetArrayElementAtIndex(i));
109109
}
110110

111111
public void Clear()
@@ -124,17 +124,17 @@ public void Clear()
124124

125125
public void OnGUI()
126126
{
127-
if (m_Asset == null)
127+
if (asset == null)
128128
return;
129129

130-
if (m_Asset.isDirty)
130+
if (asset.isDirty)
131131
{
132132
RefreshEditors();
133-
m_Asset.isDirty = false;
133+
asset.isDirty = false;
134134
}
135135

136136
bool isEditable = !VersionControl.Provider.isActive
137-
|| AssetDatabase.IsOpenForEdit(m_Asset, StatusQueryOptions.UseCachedIfPossible);
137+
|| AssetDatabase.IsOpenForEdit(asset, StatusQueryOptions.UseCachedIfPossible);
138138

139139
using (new EditorGUI.DisabledScope(!isEditable))
140140
{
@@ -183,7 +183,7 @@ public void OnGUI()
183183
{
184184
var type = kvp.Key;
185185
var title = EditorUtilities.GetContent(kvp.Value.menuItem);
186-
bool exists = m_Asset.HasSettings(type);
186+
bool exists = asset.HasSettings(type);
187187

188188
if (!exists)
189189
menu.AddItem(title, false, () => AddEffectOverride(type));
@@ -205,22 +205,26 @@ void AddEffectOverride(Type type)
205205
var effect = CreateNewEffect(type);
206206
Undo.RegisterCreatedObjectUndo(effect, "Add Effect Override");
207207

208-
// Store this new effect as a subasset so we can reference it safely afterwards
209-
AssetDatabase.AddObjectToAsset(effect, m_Asset);
208+
// Store this new effect as a subasset so we can reference it safely afterwards. Only when its not an instantiated profile
209+
if (EditorUtility.IsPersistent(asset))
210+
AssetDatabase.AddObjectToAsset(effect, asset);
210211

211212
// Grow the list first, then add - that's how serialized lists work in Unity
212213
m_SettingsProperty.arraySize++;
213214
var effectProp = m_SettingsProperty.GetArrayElementAtIndex(m_SettingsProperty.arraySize - 1);
214215
effectProp.objectReferenceValue = effect;
215216

216-
// Force save / refresh
217-
EditorUtility.SetDirty(m_Asset);
218-
AssetDatabase.SaveAssets();
219-
220217
// Create & store the internal editor object for this effect
221218
CreateEditor(effect, effectProp);
222219

223220
m_SerializedObject.ApplyModifiedProperties();
221+
222+
// Force save / refresh. Important to do this last because SaveAssets can cause effect to become null!
223+
if (EditorUtility.IsPersistent(asset))
224+
{
225+
EditorUtility.SetDirty(asset);
226+
AssetDatabase.SaveAssets();
227+
}
224228
}
225229

226230
void RemoveEffectOverride(int id)
@@ -260,7 +264,7 @@ void RemoveEffectOverride(int id)
260264
Undo.DestroyObjectImmediate(effect);
261265

262266
// Force save / refresh
263-
EditorUtility.SetDirty(m_Asset);
267+
EditorUtility.SetDirty(asset);
264268
AssetDatabase.SaveAssets();
265269
}
266270

@@ -285,7 +289,7 @@ void ResetEffectOverride(Type type, int id)
285289
Undo.RegisterCreatedObjectUndo(newEffect, "Reset Effect Override");
286290

287291
// Store this new effect as a subasset so we can reference it safely afterwards
288-
AssetDatabase.AddObjectToAsset(newEffect, m_Asset);
292+
AssetDatabase.AddObjectToAsset(newEffect, asset);
289293

290294
// Put it in the reserved space
291295
property.objectReferenceValue = newEffect;
@@ -300,7 +304,7 @@ void ResetEffectOverride(Type type, int id)
300304
Undo.DestroyObjectImmediate(prevSettings);
301305

302306
// Force save / refresh
303-
EditorUtility.SetDirty(m_Asset);
307+
EditorUtility.SetDirty(asset);
304308
AssetDatabase.SaveAssets();
305309
}
306310

PostProcessing/Editor/PostProcessVolumeEditor.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,26 @@ public override void OnInspectorGUI()
6868
var buttonNewRect = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);
6969
var buttonCopyRect = new Rect(buttonNewRect.xMax, lineRect.y, buttonWidth, lineRect.height);
7070

71-
EditorGUI.PrefixLabel(labelRect, EditorUtilities.GetContent("Profile|A reference to a profile asset."));
71+
EditorGUI.PrefixLabel(labelRect, EditorUtilities.GetContent(m_Target.HasInstantiatedProfile() ? "Profile (Instance)|A copy of a profile asset." : "Profile|A reference to a profile asset."));
7272

7373
using (var scope = new EditorGUI.ChangeCheckScope())
7474
{
7575
EditorGUI.BeginProperty(fieldRect, GUIContent.none, m_Profile);
76+
PostProcessProfile profile = null;
7677

77-
var profile = (PostProcessProfile)EditorGUI.ObjectField(fieldRect, m_Profile.objectReferenceValue, typeof(PostProcessProfile), false);
78+
if (m_Target.HasInstantiatedProfile())
79+
profile = (PostProcessProfile)EditorGUI.ObjectField(fieldRect, m_Target.profile, typeof(PostProcessProfile), false);
80+
else
81+
profile = (PostProcessProfile)EditorGUI.ObjectField(fieldRect, m_Profile.objectReferenceValue, typeof(PostProcessProfile), false);
7882

7983
if (scope.changed)
8084
{
8185
assetHasChanged = true;
86+
8287
m_Profile.objectReferenceValue = profile;
88+
89+
if (m_Target.HasInstantiatedProfile()) // Clear the instantiated profile, from now on we're using shared again.
90+
m_Target.profile = null;
8391
}
8492

8593
EditorGUI.EndProperty();
@@ -95,14 +103,16 @@ public override void OnInspectorGUI()
95103
var scene = m_Target.gameObject.scene;
96104
var asset = ProfileFactory.CreatePostProcessProfile(scene, targetName);
97105
m_Profile.objectReferenceValue = asset;
106+
m_Target.profile = null; // Make sure we're not using an instantiated profile anymore
107+
98108
assetHasChanged = true;
99109
}
100110

101-
if (showCopy && GUI.Button(buttonCopyRect, EditorUtilities.GetContent("Clone|Create a new profile and copy the content of the currently assigned profile."), EditorStyles.miniButtonRight))
111+
if (showCopy && GUI.Button(buttonCopyRect, EditorUtilities.GetContent(m_Target.HasInstantiatedProfile() ? "Save|Save the instantiated profile" : "Clone|Create a new profile and copy the content of the currently assigned profile."), EditorStyles.miniButtonRight))
102112
{
103113
// Duplicate the currently assigned profile and save it as a new profile
104-
var origin = (PostProcessProfile)m_Profile.objectReferenceValue;
105-
var path = AssetDatabase.GetAssetPath(origin);
114+
var origin = profileRef;
115+
var path = AssetDatabase.GetAssetPath(m_Profile.objectReferenceValue);
106116
path = AssetDatabase.GenerateUniqueAssetPath(path);
107117

108118
var asset = Instantiate(origin);
@@ -122,13 +132,14 @@ public override void OnInspectorGUI()
122132
AssetDatabase.Refresh();
123133

124134
m_Profile.objectReferenceValue = asset;
135+
m_Target.profile = null; // Make sure we're not using an instantiated profile anymore
125136
assetHasChanged = true;
126137
}
127138
}
128139

129140
EditorGUILayout.Space();
130141

131-
if (m_Profile.objectReferenceValue == null)
142+
if (m_Profile.objectReferenceValue == null && !m_Target.HasInstantiatedProfile())
132143
{
133144
if (assetHasChanged)
134145
m_EffectList.Clear(); // Asset wasn't null before, do some cleanup
@@ -137,14 +148,19 @@ public override void OnInspectorGUI()
137148
}
138149
else
139150
{
140-
if (assetHasChanged)
141-
RefreshEffectListEditor((PostProcessProfile)m_Profile.objectReferenceValue);
151+
if (assetHasChanged || profileRef != m_EffectList.asset) //Refresh when the user just dragged in a new asset, or when it was instantiated by code.
152+
RefreshEffectListEditor(profileRef);
142153

143154
if (!multiEdit)
144155
m_EffectList.OnGUI();
145156
}
146157

147158
serializedObject.ApplyModifiedProperties();
148159
}
160+
161+
public PostProcessProfile profileRef
162+
{
163+
get { return m_Target.HasInstantiatedProfile() ? m_Target.profile : m_Target.sharedProfile; }
164+
}
149165
}
150166
}

PostProcessing/Runtime/PostProcessProfile.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ public bool HasSettings(Type type)
100100
return false;
101101
}
102102

103+
public T GetSetting<T>() where T : PostProcessEffectSettings
104+
{
105+
foreach (var setting in settings)
106+
{
107+
if (setting is T)
108+
return setting as T;
109+
}
110+
return null;
111+
}
112+
103113
public bool TryGetSettings<T>(out T outSetting)
104114
where T : PostProcessEffectSettings
105115
{

PostProcessing/Runtime/PostProcessVolume.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ internal PostProcessProfile profileRef
112112
}
113113
}
114114

115+
public bool HasInstantiatedProfile()
116+
{
117+
return m_InternalProfile != null;
118+
}
119+
115120
int m_PreviousLayer;
116121
float m_PreviousPriority;
117122
List<Collider> m_TempColliders;

PostProcessing/Runtime/Utils/PropertySheetFactory.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ public PropertySheetFactory()
1414

1515
public PropertySheet Get(string shaderName)
1616
{
17-
return Get(Shader.Find(shaderName));
17+
var shader = Shader.Find(shaderName);
18+
19+
if (shader == null)
20+
throw new ArgumentException(string.Format("Invalid shader ({0})", shaderName));
21+
22+
return Get(shader);
1823
}
1924

2025
public PropertySheet Get(Shader shader)

0 commit comments

Comments
 (0)