Skip to content

Commit 0bb1d53

Browse files
authored
Merge pull request #287 from Unity-Technologies/Uni-35933-DisablingAutoUpdater
Uni 35933 disabling auto updater
2 parents 6911c4b + eed44bd commit 0bb1d53

File tree

3 files changed

+148
-10
lines changed

3 files changed

+148
-10
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2620,7 +2620,7 @@ static void OnContextItem (MenuCommand command)
26202620
}
26212621

26222622
/// <summary>
2623-
// Validate the menu item defined by the function above.
2623+
/// Validate the menu item defined by the function above.
26242624
/// </summary>
26252625
[MenuItem (MenuItemName, true, 30)]
26262626
public static bool OnValidateMenuItem ()
@@ -2635,6 +2635,7 @@ public static void DisplayNoSelectionDialog()
26352635
"No GameObjects selected for export.",
26362636
"Ok");
26372637
}
2638+
26382639
//
26392640
// export mesh info from Unity
26402641
//

Assets/FbxExporters/Editor/FbxPrefabAutoUpdater.cs

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using UnityEditor;
66
using System.Linq;
77
using System;
8+
using FbxExporters.Editor;
9+
using UnityEngine.TestTools;
810

911
namespace FbxExporters
1012
{
@@ -30,14 +32,18 @@ namespace FbxExporters
3032
#else
3133
public const string FBX_PREFAB_FILE = "/UnityFbxPrefab.dll";
3234
#endif
35+
36+
const string MenuItemName = "GameObject/Update from FBX";
37+
public static bool runningUnitTest = false;
38+
3339
public static string FindFbxPrefabAssetPath()
3440
{
3541
// Find guids that are scripts that look like FbxPrefab.
3642
// That catches FbxPrefabTest too, so we have to make sure.
3743
var allGuids = AssetDatabase.FindAssets("FbxPrefab t:MonoScript");
38-
foreach(var guid in allGuids) {
44+
foreach (var guid in allGuids) {
3945
var path = AssetDatabase.GUIDToAssetPath(guid);
40-
if (path.EndsWith (FBX_PREFAB_FILE)) {
46+
if (path.EndsWith(FBX_PREFAB_FILE)) {
4147
return path;
4248
}
4349
}
@@ -65,7 +71,7 @@ public static bool MayHaveFbxPrefabToFbxAsset(string prefabPath,
6571
var depPaths = AssetDatabase.GetDependencies(prefabPath, recursive: false);
6672
bool dependsOnFbxPrefab = false;
6773
bool dependsOnImportedFbx = false;
68-
foreach(var dep in depPaths) {
74+
foreach (var dep in depPaths) {
6975
if (dep == fbxPrefabScriptPath) {
7076
if (dependsOnImportedFbx) { return true; }
7177
dependsOnFbxPrefab = true;
@@ -79,7 +85,7 @@ public static bool MayHaveFbxPrefabToFbxAsset(string prefabPath,
7985
return false;
8086
}
8187

82-
static void OnPostprocessAllAssets(string [] imported, string [] deleted, string [] moved, string [] movedFrom)
88+
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFrom)
8389
{
8490
// Do not start if Auto Updater is disabled in FBX Exporter Settings
8591
if (!FbxExporters.EditorTools.ExportSettings.instance.autoUpdaterEnabled)
@@ -92,9 +98,12 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
9298
// Did we import an fbx file at all?
9399
// Optimize to not allocate in the common case of 'no'
94100
HashSet<string> fbxImported = null;
95-
foreach(var fbxModel in imported) {
101+
foreach (var fbxModel in imported) {
96102
if (IsFbxAsset(fbxModel)) {
97-
if (fbxImported == null) { fbxImported = new HashSet<string>(); }
103+
if (fbxImported == null)
104+
{
105+
fbxImported = new HashSet<string>();
106+
}
98107
fbxImported.Add(fbxModel);
99108
//Debug.Log("Tracking fbx asset " + fbxModel);
100109
} else {
@@ -116,7 +125,7 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
116125
//
117126
var fbxPrefabScriptPath = FindFbxPrefabAssetPath();
118127
var allObjectGuids = AssetDatabase.FindAssets("t:GameObject");
119-
foreach(var guid in allObjectGuids) {
128+
foreach (var guid in allObjectGuids) {
120129
var prefabPath = AssetDatabase.GUIDToAssetPath(guid);
121130
if (!IsPrefabAsset(prefabPath)) {
122131
//Debug.Log("Not a prefab: " + prefabPath);
@@ -140,8 +149,8 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
140149
//Debug.LogWarning("FbxPrefab reimport: failed to update prefab " + prefabPath);
141150
continue;
142151
}
143-
foreach(var fbxPrefabComponent in prefab.GetComponentsInChildren<FbxPrefab>()) {
144-
var fbxPrefabUtility = new FbxPrefabUtility (fbxPrefabComponent);
152+
foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren<FbxPrefab>()) {
153+
var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent);
145154
if (!fbxPrefabUtility.WantsAutoUpdate()) {
146155
//Debug.Log("Not auto-updating " + prefabPath);
147156
continue;
@@ -156,8 +165,89 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
156165
}
157166
}
158167
}
168+
/// <summary>
169+
/// Add an option "Update from FBX" in the contextual GameObject menu.
170+
/// </summary>
171+
[MenuItem(MenuItemName, false,31)]
172+
static void OnContextItem(MenuCommand command)
173+
{
174+
GameObject[] selection = null;
175+
176+
if (command == null || command.context == null)
177+
{
178+
// We were actually invoked from the top GameObject menu, so use the selection.
179+
selection = Selection.GetFiltered<GameObject>(SelectionMode.Editable | SelectionMode.TopLevel);
180+
}
181+
else
182+
{
183+
// We were invoked from the right-click menu, so use the context of the context menu.
184+
var selected = command.context as GameObject;
185+
if (selected)
186+
{
187+
selection = new GameObject[] { selected };
188+
}
189+
}
190+
191+
foreach (GameObject selectedObject in selection)
192+
{
193+
UpdateLinkedPrefab(selectedObject);
194+
}
195+
}
196+
197+
/// <summary>
198+
/// Validate the menu item defined by the function above.
199+
/// </summary>
200+
[MenuItem(MenuItemName, true,31)]
201+
public static bool OnValidateMenuItem()
202+
{
203+
GameObject[] selection = Selection.gameObjects;
204+
205+
if (selection == null || selection.Length == 0)
206+
{
207+
return false;
208+
}
209+
210+
bool containsLinkedPrefab = false;
211+
foreach (GameObject selectedObject in selection)
212+
{
213+
GameObject prefab = UnityEditor.PrefabUtility.GetPrefabParent(selectedObject) as GameObject;
214+
if (prefab && prefab.GetComponentInChildren<FbxPrefab>())
215+
{
216+
containsLinkedPrefab = true;
217+
break;
218+
}
219+
}
220+
221+
return containsLinkedPrefab;
222+
}
159223

160224

225+
static void DisplayNoSelectionDialog(string message)
226+
{
227+
UnityEditor.EditorUtility.DisplayDialog(
228+
string.Format("{0} Warning", ModelExporter.PACKAGE_UI_NAME),
229+
message,
230+
"Ok");
231+
}
232+
233+
/// <summary>
234+
/// Launch the manual update of the linked prefab specified
235+
/// </summary>
236+
public static void UpdateLinkedPrefab(GameObject prefabInstance)
237+
{
238+
GameObject prefab = UnityEditor.PrefabUtility.GetPrefabParent(prefabInstance) as GameObject;
239+
if (!prefab)
240+
{
241+
return;
242+
}
243+
244+
foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren<FbxPrefab>())
245+
{
246+
var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent);
247+
fbxPrefabUtility.SyncPrefab();
248+
}
249+
}
250+
161251
public class FbxPrefabUtility{
162252

163253
private FbxPrefab m_fbxPrefab;

Assets/FbxExporters/Editor/UnitTests/FbxPrefabAutoUpdaterTest.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ public class FbxPrefabAutoUpdaterToggleTest : ExporterTestBase
215215
[SetUp]
216216
public void Init()
217217
{
218+
// Save the initial setting for the auto updater toggle and disable it for the unit test
218219
isAutoUpdaterOn = FbxExporters.EditorTools.ExportSettings.instance.autoUpdaterEnabled;
219220
FbxExporters.EditorTools.ExportSettings.instance.autoUpdaterEnabled = false;
221+
FbxPrefabAutoUpdater.runningUnitTest = true;
220222
}
221223

222224
[Test]
@@ -265,13 +267,58 @@ public void RemappingTest()
265267
Assert.IsTrue(cubePrefabInstance.GetComponent<MeshFilter>().sharedMesh != null);
266268
Assert.IsTrue(cubePrefabInstance.transform.GetChild(0).name == "Sphere");
267269
Assert.IsTrue(cubePrefabInstance.transform.GetChild(0).GetComponent<MeshFilter>().sharedMesh != null);
270+
271+
// Testing Manual update on true prefab
272+
GameObject[] selection = new GameObject[] { cubePrefabInstance };
273+
FbxPrefabAutoUpdater.UpdateLinkedPrefab(selection[0]);
274+
Assert.IsTrue(cubePrefabInstance != null);
275+
Assert.IsTrue(cubePrefabInstance.GetComponent<MeshFilter>().sharedMesh != null);
276+
Assert.IsTrue(cubePrefabInstance.transform.GetChild(0).name == "SphereFBX");
277+
Assert.IsTrue(cubePrefabInstance.transform.GetChild(0).GetComponent<MeshFilter>().sharedMesh != null);
278+
279+
// Testing Manual update on some random object that isn't a prefab at all, the gameobject shouldn't be modified. No error is returned
280+
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
281+
FbxPrefabAutoUpdater.UpdateLinkedPrefab(quad);
282+
Assert.IsTrue(quad != null);
283+
Assert.IsTrue(quad.GetComponent<MeshFilter>().sharedMesh != null);
284+
285+
// Testing Manual update on some random prefab that doesn't have an FbxPrefab in it, the prefab shouldn't be modified. No error is returned
286+
GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);
287+
// Convert to linked prefab instance (auto-updating prefab)
288+
string prefabPath = GetRandomPrefabAssetPath();
289+
GameObject capsuleInstance = PrefabUtility.CreatePrefab(prefabPath, capsule);
290+
FbxPrefabAutoUpdater.UpdateLinkedPrefab(capsuleInstance);
291+
Assert.IsTrue(capsuleInstance != null);
292+
Assert.IsTrue(capsuleInstance.GetComponent<MeshFilter>().sharedMesh != null);
293+
294+
// Check the menu returns true because sphere3 is a linked prefab
295+
GameObject cylinder3 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
296+
GameObject sphere3 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
297+
sphere3.transform.SetParent(cylinder3.transform);
298+
GameObject sphere3Instance = ConvertToModel.Convert(sphere3, fbxFullPath: filePath);
299+
Selection.objects = new GameObject[] { sphere3Instance };
300+
Assert.IsTrue(FbxPrefabAutoUpdater.OnValidateMenuItem());
301+
302+
// Check the contextual menu returns false because there is no linked prefab in the selection, an error is returned
303+
GameObject cylinder4 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
304+
GameObject sphere4 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
305+
sphere4.transform.SetParent(cylinder4.transform);
306+
Selection.objects = new GameObject[] { cylinder4, sphere4 };
307+
Assert.IsFalse(FbxPrefabAutoUpdater.OnValidateMenuItem());
308+
309+
// Assert is true because sphere 3 instance is a linked prefab and all the selection is taken into account
310+
sphere3Instance.transform.SetParent(quad.transform);
311+
Selection.objects = new GameObject[] { quad, sphere3Instance };
312+
Assert.IsTrue(FbxPrefabAutoUpdater.OnValidateMenuItem());
268313
}
269314

270315

271316
[TearDown]
272317
public void stopTest()
273318
{
319+
// Put back the initial setting for the auto-updater toggle
274320
FbxExporters.EditorTools.ExportSettings.instance.autoUpdaterEnabled = isAutoUpdaterOn;
321+
FbxPrefabAutoUpdater.runningUnitTest = false;
275322
}
276323
}
277324
}

0 commit comments

Comments
 (0)