Skip to content

Commit 9c16110

Browse files
committed
Merge branch 'master' into UNI-39477-select-LOD-to-export
2 parents 0bdb0f2 + b9355a0 commit 9c16110

File tree

10 files changed

+332
-60
lines changed

10 files changed

+332
-60
lines changed

Assets/FbxExporters/Editor/ConvertToModel.cs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,29 @@ public static GameObject Convert (
117117
string directoryFullPath = null,
118118
string fbxFullPath = null)
119119
{
120+
// Only create the prefab (no FBX export) if we have selected the root of a model prefab instance.
121+
// Children of model prefab instances will also have "model prefab instance"
122+
// as their prefab type, so it is important that it is the root that is selected.
123+
//
124+
// e.g. If I have the following hierarchy:
125+
// Cube
126+
// -- Sphere
127+
//
128+
// Both the Cube and Sphere will have ModelPrefabInstance as their prefab type.
129+
// However, when selecting the Sphere to convert, we don't want to connect it to the
130+
// existing FBX but create a new FBX containing just the sphere.
131+
PrefabType unityPrefabType = PrefabUtility.GetPrefabType(toConvert);
132+
if (unityPrefabType == PrefabType.ModelPrefabInstance && toConvert.Equals(PrefabUtility.FindPrefabRoot(toConvert))) {
133+
// don't re-export fbx
134+
// create prefab out of model instance in scene, link to existing fbx
135+
var mainAsset = PrefabUtility.GetPrefabParent(toConvert) as GameObject;
136+
var mainAssetRelPath = AssetDatabase.GetAssetPath(mainAsset);
137+
var mainAssetAbsPath = Directory.GetParent(Application.dataPath) + "/" + mainAssetRelPath;
138+
SetupFbxPrefab(toConvert, mainAsset, mainAssetRelPath, mainAssetAbsPath);
139+
140+
return toConvert;
141+
}
142+
120143
if (string.IsNullOrEmpty(fbxFullPath)) {
121144
// Generate a unique filename.
122145
if (string.IsNullOrEmpty (directoryFullPath)) {
@@ -155,12 +178,27 @@ public static GameObject Convert (
155178
// relative to the project, not relative to the assets folder.
156179
var unityMainAsset = AssetDatabase.LoadMainAssetAtPath (projectRelativePath) as GameObject;
157180
if (!unityMainAsset) {
158-
throw new System.Exception ("Failed to convert " + toConvert.name);;
181+
throw new System.Exception ("Failed to convert " + toConvert.name);
159182
}
160183

161184
// Copy the mesh/materials from the FBX
162185
UpdateFromSourceRecursive (toConvert, unityMainAsset);
163186

187+
SetupFbxPrefab (toConvert, unityMainAsset, projectRelativePath, fbxFullPath);
188+
189+
toConvert.name = Path.GetFileNameWithoutExtension (fbxFullPath);
190+
return toConvert;
191+
}
192+
193+
194+
/// <summary>
195+
/// Create the prefab and connect it to the given fbx asset.
196+
/// </summary>
197+
/// <param name="toConvert">Hierarchy to convert.</param>
198+
/// <param name="unityMainAsset">Main asset in the FBX.</param>
199+
/// <param name="projectRelativePath">Fbx project relative path.</param>
200+
/// <param name="fbxFullPath">Fbx full path.</param>
201+
public static void SetupFbxPrefab(GameObject toConvert, GameObject unityMainAsset, string projectRelativePath, string fbxFullPath){
164202
// Set up the FbxPrefab component so it will auto-update.
165203
// Make sure to delete whatever FbxPrefab history we had.
166204
var fbxPrefab = toConvert.GetComponent<FbxPrefab>();
@@ -179,9 +217,6 @@ public static GameObject Convert (
179217
string.Format("Failed to create prefab asset in [{0}] from fbx [{1}]",
180218
prefabFileName, fbxFullPath));
181219
}
182-
183-
toConvert.name = Path.GetFileNameWithoutExtension (fbxFullPath);
184-
return toConvert;
185220
}
186221

187222
/// <summary>

Assets/FbxExporters/Editor/FbxExportSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ public static string[] DCCVendorLocations
436436

437437
// Note: default values are set in LoadDefaults().
438438
public bool mayaCompatibleNames = true;
439-
public bool centerObjects = true;
439+
public bool centerObjects = false;
440440
public bool autoUpdaterEnabled = true;
441441
public bool launchAfterInstallation = true;
442442
public bool HideSendToUnityMenu = true;

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,6 +2707,7 @@ public enum TransformExportType { Local, Global, Reset };
27072707
public int ExportAll (
27082708
IEnumerable<UnityEngine.Object> unityExportSet,
27092709
Dictionary<GameObject, AnimationOnlyExportData> animationExportData,
2710+
TransformExportType exportType = TransformExportType.Global,
27102711
ExportSettings.LODExportType lodExportType = ExportSettings.LODExportType.All)
27112712
{
27122713
exportCancelled = false;
@@ -2811,10 +2812,8 @@ public int ExportAll (
28112812
}
28122813

28132814
Vector3 center = Vector3.zero;
2814-
var exportType = TransformExportType.Reset;
2815-
if(revisedExportSet.Count != 1){
2815+
if(exportType == TransformExportType.Global){
28162816
center = ExportSettings.centerObjects? FindCenter(revisedExportSet) : Vector3.zero;
2817-
exportType = TransformExportType.Global;
28182817
}
28192818

28202819
foreach (var unityGo in revisedExportSet) {
@@ -3604,6 +3603,7 @@ public static string ExportObjects (
36043603
string filePath,
36053604
UnityEngine.Object[] objects = null,
36063605
AnimationExportType exportType = AnimationExportType.all,
3606+
TransformExportType transformExportType = TransformExportType.Global,
36073607
ExportSettings.LODExportType lodExportType = ExportSettings.LODExportType.All)
36083608
{
36093609
LastFilePath = filePath;
@@ -3645,7 +3645,7 @@ public static string ExportObjects (
36453645
break;
36463646
}
36473647

3648-
if (fbxExporter.ExportAll (objects, animationExportData, lodExportType) > 0) {
3648+
if (fbxExporter.ExportAll (objects, animationExportData, transformExportType, lodExportType) > 0) {
36493649
string message = string.Format ("Successfully exported: {0}", filePath);
36503650
UnityEngine.Debug.Log (message);
36513651

@@ -3658,9 +3658,10 @@ public static string ExportObjects (
36583658
public static string ExportObject (
36593659
string filePath, UnityEngine.Object root,
36603660
AnimationExportType exportType = AnimationExportType.all,
3661+
TransformExportType transformExportType = TransformExportType.Reset,
36613662
ExportSettings.LODExportType lodExportType = ExportSettings.LODExportType.All)
36623663
{
3663-
return ExportObjects(filePath, new Object[] { root }, exportType, lodExportType);
3664+
return ExportObjects(filePath, new Object[] { root }, exportType, transformExportType, lodExportType);
36643665
}
36653666

36663667
private static void EnsureDirectory (string path)

Assets/FbxExporters/Editor/FbxPrefabAutoUpdater.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace FbxExporters
3333
const string MenuItemName = "GameObject/Update from FBX";
3434
public static bool runningUnitTest = false;
3535

36+
public static bool Verbose { private set {;} get { return EditorTools.ExportSettings.instance.Verbose; } }
37+
3638
public static string FindFbxPrefabAssetPath()
3739
{
3840
// Find guids that are scripts that look like FbxPrefab.
@@ -90,7 +92,9 @@ static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[]
9092
return;
9193
}
9294

93-
//Debug.Log("Postprocessing...");
95+
if (Verbose) {
96+
Debug.Log ("Postprocessing...");
97+
}
9498

9599
// Did we import an fbx file at all?
96100
// Optimize to not allocate in the common case of 'no'
@@ -102,13 +106,19 @@ static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[]
102106
fbxImported = new HashSet<string>();
103107
}
104108
fbxImported.Add(fbxModel);
105-
//Debug.Log("Tracking fbx asset " + fbxModel);
109+
if (Verbose) {
110+
Debug.Log ("Tracking fbx asset " + fbxModel);
111+
}
106112
} else {
107-
//Debug.Log("Not an fbx asset " + fbxModel);
113+
if (Verbose) {
114+
Debug.Log ("Not an fbx asset " + fbxModel);
115+
}
108116
}
109117
}
110118
if (fbxImported == null) {
111-
//Debug.Log("No fbx imported");
119+
if(Verbose){
120+
Debug.Log("No fbx imported");
121+
}
112122
return;
113123
}
114124

@@ -125,14 +135,20 @@ static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[]
125135
foreach (var guid in allObjectGuids) {
126136
var prefabPath = AssetDatabase.GUIDToAssetPath(guid);
127137
if (!IsPrefabAsset(prefabPath)) {
128-
//Debug.Log("Not a prefab: " + prefabPath);
138+
if (Verbose) {
139+
Debug.Log ("Not a prefab: " + prefabPath);
140+
}
129141
continue;
130142
}
131143
if (!MayHaveFbxPrefabToFbxAsset(prefabPath, fbxPrefabScriptPath, fbxImported)) {
132-
//Debug.Log("No dependence: " + prefabPath);
144+
if(Verbose){
145+
Debug.Log("No dependence: " + prefabPath);
146+
}
133147
continue;
134148
}
135-
//Debug.Log("Considering updating prefab " + prefabPath);
149+
if (Verbose) {
150+
Debug.Log ("Considering updating prefab " + prefabPath);
151+
}
136152

137153
// We're now guaranteed that this is a prefab, and it depends
138154
// on the FbxPrefab script, and it depends on an Fbx file that
@@ -143,21 +159,29 @@ static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[]
143159
// update the prefab anyway).
144160
var prefab = AssetDatabase.LoadMainAssetAtPath(prefabPath) as GameObject;
145161
if (!prefab) {
146-
//Debug.LogWarning("FbxPrefab reimport: failed to update prefab " + prefabPath);
162+
if (Verbose) {
163+
Debug.LogWarning ("FbxPrefab reimport: failed to update prefab " + prefabPath);
164+
}
147165
continue;
148166
}
149167
foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren<FbxPrefab>()) {
150168
var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent);
151169
if (!fbxPrefabUtility.WantsAutoUpdate()) {
152-
//Debug.Log("Not auto-updating " + prefabPath);
170+
if (Verbose) {
171+
Debug.Log ("Not auto-updating " + prefabPath);
172+
}
153173
continue;
154174
}
155175
var fbxAssetPath = fbxPrefabUtility.GetFbxAssetPath();
156176
if (!fbxImported.Contains(fbxAssetPath)) {
157-
//Debug.Log("False-positive dependence: " + prefabPath + " via " + fbxAssetPath);
177+
if (Verbose) {
178+
Debug.Log ("False-positive dependence: " + prefabPath + " via " + fbxAssetPath);
179+
}
158180
continue;
159181
}
160-
//Debug.Log("Updating " + prefabPath + "...");
182+
if (Verbose) {
183+
Debug.Log ("Updating " + prefabPath + "...");
184+
}
161185
fbxPrefabUtility.SyncPrefab();
162186
}
163187
}
@@ -347,7 +371,7 @@ public string GetFBXObjectName(string unityObjectName)
347371
/// </summary>
348372
[System.Diagnostics.Conditional("FBXEXPORTER_DEBUG")]
349373
public static void Log(string message) {
350-
Debug.Log("Fbx prefab update: " + message);
374+
Debug.Log ("Fbx prefab update: " + message);
351375
}
352376

353377
[System.Diagnostics.Conditional("FBXEXPORTER_DEBUG")]
@@ -1226,7 +1250,10 @@ public HashSet<GameObject> ImplementUpdates(FbxPrefab prefabInstance)
12261250
var componentName = kvp.Key;
12271251
// We rename the node before the loop, so the component name now has the FBX object name, instead of the unity one that was saved
12281252
componentName = m_fbxPrefabUtility.GetFBXObjectName(componentName);
1229-
Debug.Log("Component: " + componentName);
1253+
1254+
if (Verbose) {
1255+
Debug.Log ("Component: " + componentName);
1256+
}
12301257
var fbxComponents = kvp.Value;
12311258
var prefabXfo = prefabNodes[componentName];
12321259
updatedNodes.Add(prefabXfo.gameObject);

Assets/FbxExporters/Editor/ManualUpdateEditorWindow.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public class ManualUpdateEditorWindow : EditorWindow
1818

1919
List<string> m_nodeNameToSuggest;
2020

21+
public bool Verbose { private set {;} get { return FbxExporters.EditorTools.ExportSettings.instance.Verbose; } }
22+
2123
public void Init(FbxPrefabAutoUpdater.FbxPrefabUtility fbxPrefabUtility, FbxPrefab fbxPrefab)
2224
{
2325
FbxPrefabAutoUpdater.FbxPrefabUtility.UpdateList updates = new FbxPrefabAutoUpdater.FbxPrefabUtility.UpdateList(new FbxPrefabAutoUpdater.FbxPrefabUtility.FbxRepresentation(fbxPrefab.FbxHistory), fbxPrefab.FbxModel.transform, fbxPrefab);
@@ -137,7 +139,10 @@ void ApplyChanges()
137139
stringpair.UnityObjectName = m_nodesToDestroy[i];
138140

139141
m_fbxPrefab.NameMapping.Add(stringpair);
140-
Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
142+
143+
if (Verbose) {
144+
Debug.Log ("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
145+
}
141146
}
142147
}
143148

@@ -161,11 +166,15 @@ void ApplyChanges()
161166
stringpair.UnityObjectName = currentUnityNodeName;
162167
m_fbxPrefab.NameMapping.Add(stringpair);
163168

164-
Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
169+
if (Verbose) {
170+
Debug.Log ("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
171+
}
165172
}
166173
else
167174
{
168-
Debug.Log("ALREADY Mapped Unity: " + currentUnityNodeName + " to FBX: " + options[selectedNodesToRename[i]].text);
175+
if (Verbose) {
176+
Debug.Log ("ALREADY Mapped Unity: " + currentUnityNodeName + " to FBX: " + options [selectedNodesToRename [i]].text);
177+
}
169178
}
170179
}
171180
}

Assets/FbxExporters/Editor/UnitTests/ConvertToModelTest.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,5 +256,59 @@ public void TestInstanceNameMatchesFilename()
256256

257257
Assert.AreEqual (Path.GetFileNameWithoutExtension (path), cube.name);
258258
}
259+
260+
[Test]
261+
public void TestConvertModelInstance()
262+
{
263+
// expected result: prefab is linked to originally exported
264+
// fbx and no new fbx is created.
265+
266+
// create hierarchy (Cube->Sphere)
267+
var cube = GameObject.CreatePrimitive (PrimitiveType.Cube);
268+
var sphere = GameObject.CreatePrimitive (PrimitiveType.Sphere);
269+
270+
sphere.transform.SetParent (cube.transform);
271+
272+
// export using regular model export
273+
var filename = GetRandomFileNamePath();
274+
GameObject fbxObj = ExportSelection (filename, cube);
275+
276+
// add back to scene
277+
GameObject fbxInstance = PrefabUtility.InstantiatePrefab (fbxObj) as GameObject;
278+
Assert.That (fbxInstance, Is.Not.Null);
279+
280+
// attach some components
281+
var rigidBody = fbxInstance.AddComponent<Rigidbody> ();
282+
Assert.That (rigidBody, Is.Not.Null);
283+
284+
var instanceSphere = fbxInstance.transform.GetChild (0);
285+
Assert.That (instanceSphere, Is.Not.Null);
286+
287+
var boxCollider = instanceSphere.gameObject.AddComponent<BoxCollider> ();
288+
Assert.That (boxCollider, Is.Not.Null);
289+
290+
// convert to prefab
291+
GameObject converted = ConvertToModel.Convert (fbxInstance, Path.GetDirectoryName(filename));
292+
Assert.That (converted, Is.EqualTo (fbxInstance));
293+
294+
// check meshes link to original fbx
295+
var prefabCubeMesh = fbxInstance.GetComponent<MeshFilter>().sharedMesh;
296+
Assert.That (prefabCubeMesh, Is.Not.Null);
297+
298+
var fbxObjAssetPath = AssetDatabase.GetAssetPath (fbxObj);
299+
300+
Assert.That (AssetDatabase.GetAssetPath (prefabCubeMesh), Is.EqualTo (fbxObjAssetPath));
301+
302+
var prefabSphere = fbxInstance.transform.GetChild (0);
303+
Assert.That (prefabSphere, Is.Not.Null);
304+
var prefabSphereMesh = prefabSphere.GetComponent<MeshFilter> ().sharedMesh;
305+
Assert.That (prefabSphere, Is.Not.Null);
306+
307+
Assert.That (AssetDatabase.GetAssetPath (prefabSphereMesh), Is.EqualTo (fbxObjAssetPath));
308+
309+
// check that components are still there
310+
Assert.That (fbxInstance.GetComponent<Rigidbody>(), Is.Not.Null);
311+
Assert.That (prefabSphere.GetComponent<BoxCollider> (), Is.Not.Null);
312+
}
259313
}
260314
}

0 commit comments

Comments
 (0)