public override void OnInspectorGUI() { SerializedProperty m_GameObjectProp = serializedObject.FindProperty("m_nameMapping"); FbxPrefab fbxPrefab = (FbxPrefab)target; // We can only change these settings when applied to a prefab. bool isDisabled = string.IsNullOrEmpty(AssetDatabase.GetAssetPath(fbxPrefab)); if (isDisabled) { EditorGUILayout.HelpBox("Please select a prefab. You can't edit an instance in the scene.", MessageType.Info); } EditorGUI.BeginDisabledGroup(isDisabled); FbxPrefabUtility fbxPrefabUtility = new FbxPrefabUtility(fbxPrefab); var oldFbxAsset = fbxPrefabUtility.FbxAsset; var newFbxAsset = EditorGUILayout.ObjectField(new GUIContent("Source FBX Asset", "The FBX file that is linked to this Prefab"), oldFbxAsset, typeof(GameObject), allowSceneObjects: false) as GameObject; if (newFbxAsset && !FbxPrefabAutoUpdater.IsFbxAsset(UnityEditor.AssetDatabase.GetAssetPath(newFbxAsset))) { Debug.LogError("FbxPrefab must point to an FBX asset (or none)."); } else if (newFbxAsset != oldFbxAsset) { fbxPrefabUtility.SetSourceModel(newFbxAsset); } EditorGUI.EndDisabledGroup(); EditorGUILayout.PropertyField(m_GameObjectProp, true); #if FBXEXPORTER_DEBUG if (GUILayout.Button("Update prefab manually...")) { // Get existing open window or if none, make a new one: ManualUpdateEditorWindow window = (ManualUpdateEditorWindow)EditorWindow.GetWindow(typeof(ManualUpdateEditorWindow)); window.Init(fbxPrefabUtility, fbxPrefab); window.Show(); } EditorGUILayout.LabelField("Debug info:"); try { fbxPrefabUtility.GetFbxHistory().ToJson(); } catch (System.Exception xcp) { Debug.LogException(xcp); } EditorGUILayout.SelectableLabel(fbxPrefabUtility.GetFbxHistoryString()); #endif serializedObject.ApplyModifiedProperties(); }
public static void SetupFbxPrefab(GameObject toSetUp, GameObject unityMainAsset) { if (toSetUp == null) { throw new System.ArgumentNullException("toSetUp"); } // Set up the FbxPrefab component so it will auto-update. // Make sure to delete whatever FbxPrefab history we had. var fbxPrefab = toSetUp.GetComponent <FbxPrefab>(); if (fbxPrefab) { Object.DestroyImmediate(fbxPrefab); } fbxPrefab = toSetUp.AddComponent <FbxPrefab>(); var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefab); fbxPrefabUtility.SetSourceModel(unityMainAsset); }
public static void UpdateLinkedPrefab(GameObject prefabOrInstance) { // Find the prefab, bail if this is neither a prefab nor an instance. GameObject prefab; switch (PrefabUtility.GetPrefabType(prefabOrInstance)) { case PrefabType.Prefab: prefab = prefabOrInstance; break; case PrefabType.PrefabInstance: prefab = PrefabUtility.GetCorrespondingObjectFromSource(prefabOrInstance) as GameObject; break; default: return; } foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren <FbxPrefab>()) { // Launch the manual update UI to allow the user to fix // renamed nodes (or auto-update if there's nothing to rename). var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent); if (UnityEditor.Formats.Fbx.Exporter.ExportSettings.instance.AutoUpdaterEnabled || runningUnitTest) { fbxPrefabUtility.SyncPrefab(); } else { ManualUpdateEditorWindow window = (ManualUpdateEditorWindow)EditorWindow.GetWindow(typeof(ManualUpdateEditorWindow)); window.Init(fbxPrefabUtility, fbxPrefabComponent); window.Show(); } } }
public void Init(FbxPrefabUtility fbxPrefabUtility, FbxPrefab fbxPrefab) { if (fbxPrefab == null) { return; } FbxPrefabUtility.UpdateList updates = new FbxPrefabUtility.UpdateList(new FbxRepresentation(fbxPrefab.FbxHistory), fbxPrefab.FbxModel.transform, fbxPrefab); m_fbxPrefabUtility = fbxPrefabUtility; m_fbxPrefab = fbxPrefab; // Convert Hashset into List m_nodesToCreate = updates.NodesToCreate.ToList(); m_nodesToDestroy = updates.NodesToDestroy.ToList(); m_nodesToRename = updates.NodesToRename.ToList(); // Create the dropdown list m_nodeNameToSuggest = new List <string>(); m_nodeNameToSuggest.AddRange(m_nodesToCreate); m_nodeNameToSuggest.AddRange(m_nodesToRename); // Keep track of the selected combo option in each type selectedNodesToDestroy = new int[m_nodesToDestroy.Count]; selectedNodesToRename = new int[m_nodesToRename.Count]; // Default option for nodes to rename. Shows the current name mapping for (int i = 0; i < m_nodesToRename.Count; i++) { for (int j = 0; j < m_nodeNameToSuggest.Count; j++) { if (m_nodeNameToSuggest[j] == m_nodesToRename[i]) { // Add extra 1 for the [Delete] option selectedNodesToRename[i] = j + 1; } } } }
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFrom) { // Do not start if Auto Updater is disabled in FBX Exporter Settings if (!UnityEditor.Formats.Fbx.Exporter.ExportSettings.instance.AutoUpdaterEnabled) { return; } if (Verbose) { Debug.Log("Postprocessing..."); } // Did we import an fbx file at all? // Optimize to not allocate in the common case of 'no' HashSet <string> fbxImported = null; foreach (var fbxModel in imported) { if (IsFbxAsset(fbxModel)) { if (fbxImported == null) { fbxImported = new HashSet <string>(); } fbxImported.Add(fbxModel); if (Verbose) { Debug.Log("Tracking fbx asset " + fbxModel); } } else { if (Verbose) { Debug.Log("Not an fbx asset " + fbxModel); } } } if (fbxImported == null) { if (Verbose) { Debug.Log("No fbx imported"); } return; } // // Iterate over all the prefabs that have an FbxPrefab component that // points to an FBX file that got (re)-imported. // // There's no one-line query to get those, so we search for a much // larger set and whittle it down, hopefully without needing to // load the asset into memory if it's not necessary. // var fbxPrefabScriptPath = FindFbxPrefabAssetPath(); var allObjectGuids = AssetDatabase.FindAssets("t:GameObject"); foreach (var guid in allObjectGuids) { var prefabPath = AssetDatabase.GUIDToAssetPath(guid); if (!IsPrefabAsset(prefabPath)) { if (Verbose) { Debug.Log("Not a prefab: " + prefabPath); } continue; } if (!MayHaveFbxPrefabToFbxAsset(prefabPath, fbxPrefabScriptPath, fbxImported)) { if (Verbose) { Debug.Log("No dependence: " + prefabPath); } continue; } if (Verbose) { Debug.Log("Considering updating prefab " + prefabPath); } // We're now guaranteed that this is a prefab, and it depends // on the FbxPrefab script, and it depends on an Fbx file that // was imported. // // To be sure it has an FbxPrefab component that points to an // Fbx file, we need to load the asset (which we need to do to // update the prefab anyway). var prefab = AssetDatabase.LoadMainAssetAtPath(prefabPath) as GameObject; if (!prefab) { if (Verbose) { Debug.LogWarning("FbxPrefab reimport: failed to update prefab " + prefabPath); } continue; } foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren <FbxPrefab>()) { var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent); if (!fbxPrefabUtility.WantsAutoUpdate()) { if (Verbose) { Debug.Log("Not auto-updating " + prefabPath); } continue; } var fbxAssetPath = fbxPrefabUtility.FbxAssetPath; if (!fbxImported.Contains(fbxAssetPath)) { if (Verbose) { Debug.Log("False-positive dependence: " + prefabPath + " via " + fbxAssetPath); } continue; } if (Verbose) { Debug.Log("Updating " + prefabPath + "..."); } fbxPrefabUtility.SyncPrefab(); } } }