Skip to content

Commit 014767f

Browse files
author
Benoit Hudson
committed
pr#378 - fix review comments about when we create new prefabs
1 parent 0adc8ee commit 014767f

File tree

2 files changed

+70
-14
lines changed

2 files changed

+70
-14
lines changed

Assets/FbxExporters/Editor/ConvertToModel.cs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,27 @@ public static GameObject Convert (
137137
string prefabFullPath = null,
138138
EditorTools.ConvertToPrefabSettingsSerialize exportOptions = null)
139139
{
140-
// If we selected the something that's already backed by an FBX, don't export.
140+
// If we selected the something that's already backed by an
141+
// FBX, don't export.
141142
var mainAsset = GetOrCreateFbxAsset (toConvert, fbxDirectoryFullPath, fbxFullPath, exportOptions);
142143

144+
// If we selected a prefab *instance* then break the
145+
// connection. We only want to update an existing prefab if
146+
// we're converting an existing prefab (not an instance).
147+
if (PrefabUtility.GetPrefabType(toConvert) == PrefabType.PrefabInstance) {
148+
PrefabUtility.DisconnectPrefabInstance(toConvert);
149+
}
150+
143151
// Get 'toConvert' into an editable state. We can't edit
144152
// assets, and toConvert might be an asset.
145153
var toConvertInstance = GetOrCreateInstance (toConvert);
146154

147155
// Set it up to track the FbxPrefab.
148156
SetupFbxPrefab (toConvertInstance, mainAsset);
149157

150-
// Now get 'toConvertInstance' into a prefab. If toConvert is already a prefab,
151-
// this is equivalent to an 'apply' ; if it's not, we're creating a new prefab.
158+
// Now get 'toConvertInstance' into a prefab. If toConvert is
159+
// already a prefab, this is equivalent to an 'apply' ; if it's
160+
// not, we're creating a new prefab.
152161
var prefab = ApplyOrCreatePrefab (toConvertInstance, prefabDirectoryFullPath, prefabFullPath);
153162

154163
if (toConvertInstance == toConvert) {
@@ -166,10 +175,11 @@ public static GameObject Convert (
166175
}
167176

168177
/// <summary>
169-
/// Check whether GetOrCreateFbxAsset will be exporting an fbx file, or reusing one.
178+
/// Check whether <see>Convert</see> will be exporting an fbx file,
179+
/// or reusing one.
170180
/// </summary>
171-
public static bool WillExportFbx(GameObject go) {
172-
return GetFbxAssetOrNull(go) == null;
181+
public static bool WillExportFbx(GameObject toConvert) {
182+
return GetFbxAssetOrNull(toConvert) == null;
173183
}
174184

175185
/// <summary>
@@ -266,24 +276,46 @@ public static GameObject GetOrCreateInstance(GameObject toConvert)
266276
}
267277

268278
/// <summary>
269-
/// Check whether ApplyOrCreatePrefab will be creating a new prefab, or updating one.
279+
/// Check whether <see>Convert</see> will be creating a new prefab, or
280+
/// updating one.
281+
///
282+
/// Note that ApplyOrCreatePrefab will create in different
283+
/// circumstances than Convert will.
270284
/// </summary>
271-
public static bool WillCreatePrefab(GameObject go) {
272-
return PrefabUtility.GetPrefabType(go) != PrefabType.PrefabInstance;
285+
public static bool WillCreatePrefab(GameObject toConvert) {
286+
return PrefabUtility.GetPrefabType(toConvert) != PrefabType.Prefab;
273287
}
274288

275289
/// <summary>
276290
/// Create a prefab from 'instance', or apply 'instance' to its
277291
/// prefab if it's already an instance of a prefab.
278292
///
279-
/// Return the new or updated prefab.
293+
/// If it's an instance of a model prefab (an fbx file) we will
294+
/// lose that connection and point to a new prefab file.
295+
///
296+
/// To avoid applying to an existing prefab, break the prefab
297+
/// connection with <c>PrefabUtility.DisconnectPrefabInstance</c>.
298+
///
299+
/// Returns the new or updated prefab.
280300
/// </summary>
301+
/// <param name="instance">A GameObject in the scene. After this
302+
/// call, it will be a prefab instance (it might already be
303+
/// one).</param>
304+
/// <param name="prefabFullPath">The full path to a prefab file we
305+
/// will create. Ignored if <paramref name="instance"/> is a
306+
/// prefab instance already. May be null, in which case we'll use <paramref
307+
/// name="prefabDirectoryFullPath"/> to generate a new name</param>
308+
/// <param name="prefabDirectoryFullPath">The full path to a
309+
/// directory that will hold the new prefab. Ignored if <paramref
310+
/// name="instance"/> is a prefab instance already. Ignored if
311+
/// <paramref name="prefabFullPath"/> is provided. May be null, in
312+
/// which case we'll use the project export settings.</param>
313+
/// <returns>The new or existing prefab.</returns>
281314
public static GameObject ApplyOrCreatePrefab(GameObject instance,
282315
string prefabDirectoryFullPath = null,
283316
string prefabFullPath = null)
284317
{
285318
if(PrefabUtility.GetPrefabType(instance) == PrefabType.PrefabInstance) {
286-
// Apply: there's already a prefab.
287319
return PrefabUtility.ReplacePrefab(instance, PrefabUtility.GetPrefabParent(instance));
288320
}
289321

Assets/FbxExporters/Editor/UnitTests/ConvertToModelTest.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,24 +115,48 @@ public void TestStaticHelpers()
115115
Assert.AreEqual(1, a.GetComponents<FbxPrefab>().Length);
116116
}
117117

118-
// Test ApplyOrCreatePrefab and WillCreatePrefab
118+
// Test ApplyOrCreatePrefab
119119
{
120120
// Create a hierarchy that isn't a prefab, apply it (creating a new prefab).
121121
var a = CreateHierarchy();
122-
Assert.That(ConvertToModel.WillCreatePrefab(a));
122+
123123
var aPath = GetRandomPrefabAssetPath();
124124
var aPrefab = ConvertToModel.ApplyOrCreatePrefab(a, prefabFullPath: aPath);
125125
Assert.AreEqual(aPrefab, PrefabUtility.GetPrefabParent(a));
126126

127127
// Now apply it again (replacing aPrefab). Make sure we use the
128128
// same file rather than creating a new one.
129129
var bPath = GetRandomPrefabAssetPath();
130-
Assert.That(!ConvertToModel.WillCreatePrefab(a));
131130
var bPrefab = ConvertToModel.ApplyOrCreatePrefab(a, prefabFullPath: bPath);
132131
Assert.AreEqual(bPrefab, PrefabUtility.GetPrefabParent(a));
133132
Assert.AreEqual(aPath, AssetDatabase.GetAssetPath(bPrefab));
134133
}
135134

135+
// Test WillCreatePrefab
136+
// Remember that it answers what convert will do, not what
137+
// apply-or-create will do (it's different).
138+
{
139+
// Create depends on prefab type.
140+
var a = CreateHierarchy();
141+
142+
// None => create
143+
Assert.That(ConvertToModel.WillCreatePrefab(a));
144+
145+
// PrefabInstance => create
146+
// Prefab => don't create
147+
// DisconnectedPrefabInstance => create
148+
var aPrefab = PrefabUtility.CreatePrefab(GetRandomPrefabAssetPath(), a);
149+
Assert.That(ConvertToModel.WillCreatePrefab(a));
150+
Assert.That(!ConvertToModel.WillCreatePrefab(aPrefab));
151+
PrefabUtility.DisconnectPrefabInstance(a);
152+
Assert.That(ConvertToModel.WillCreatePrefab(a));
153+
154+
// ModelPrefabInstance or ModelPrefab => create
155+
var aFbx = ExportToFbx(a);
156+
Assert.That(ConvertToModel.WillCreatePrefab(aFbx));
157+
Assert.That(ConvertToModel.WillCreatePrefab(PrefabUtility.InstantiatePrefab(aFbx) as GameObject));
158+
}
159+
136160
// Test CopyComponents
137161
{
138162
var a = GameObject.CreatePrimitive (PrimitiveType.Cube);

0 commit comments

Comments
 (0)