ManualUpdateEditorWindow.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #if !UNITY_2018_3_OR_NEWER
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. using UnityEngine.Formats.Fbx.Exporter;
  6. using System.Linq;
  7. namespace UnityEditor.Formats.Fbx.Exporter
  8. {
  9. internal class ManualUpdateEditorWindow : EditorWindow
  10. {
  11. int[] selectedNodesToDestroy;
  12. int[] selectedNodesToRename;
  13. FbxPrefabUtility m_fbxPrefabUtility;
  14. FbxPrefab m_fbxPrefab;
  15. GUIContent[] options;
  16. List<string> m_nodesToCreate;
  17. List<string> m_nodesToDestroy;
  18. List<string> m_nodesToRename;
  19. List<string> m_nodeNameToSuggest;
  20. public bool Verbose { get { return UnityEditor.Formats.Fbx.Exporter.ExportSettings.instance.VerboseProperty; } }
  21. public void Init(FbxPrefabUtility fbxPrefabUtility, FbxPrefab fbxPrefab)
  22. {
  23. if(fbxPrefab == null)
  24. {
  25. return;
  26. }
  27. FbxPrefabUtility.UpdateList updates = new FbxPrefabUtility.UpdateList(new FbxRepresentation(fbxPrefab.FbxHistory), fbxPrefab.FbxModel.transform, fbxPrefab);
  28. m_fbxPrefabUtility = fbxPrefabUtility;
  29. m_fbxPrefab = fbxPrefab;
  30. // Convert Hashset into List
  31. m_nodesToCreate = updates.NodesToCreate.ToList();
  32. m_nodesToDestroy = updates.NodesToDestroy.ToList();
  33. m_nodesToRename = updates.NodesToRename.ToList();
  34. // Create the dropdown list
  35. m_nodeNameToSuggest = new List<string>();
  36. m_nodeNameToSuggest.AddRange(m_nodesToCreate);
  37. m_nodeNameToSuggest.AddRange(m_nodesToRename);
  38. // Keep track of the selected combo option in each type
  39. selectedNodesToDestroy = new int[m_nodesToDestroy.Count];
  40. selectedNodesToRename = new int[m_nodesToRename.Count];
  41. // Default option for nodes to rename. Shows the current name mapping
  42. for (int i = 0; i < m_nodesToRename.Count; i++)
  43. {
  44. for (int j = 0; j < m_nodeNameToSuggest.Count; j++)
  45. {
  46. if (m_nodeNameToSuggest[j] == m_nodesToRename[i])
  47. {
  48. // Add extra 1 for the [Delete] option
  49. selectedNodesToRename[i] = j + 1;
  50. }
  51. }
  52. }
  53. }
  54. void OnGUI()
  55. {
  56. // If there is nothing to map, sync prefab automatically and close the window
  57. if (m_nodesToDestroy.Count == 0 && m_nodesToRename.Count == 0)
  58. {
  59. m_fbxPrefabUtility.SyncPrefab();
  60. Close();
  61. }
  62. //Titles of the columns
  63. GUILayout.BeginHorizontal();
  64. GUILayout.Label("Unity Names", EditorStyles.boldLabel);
  65. GUILayout.Label("FBX Names", EditorStyles.boldLabel);
  66. GUILayout.EndHorizontal();
  67. // List of nodes that will be destroyed on the Unity object, unless the user wants to map them
  68. for (int i = 0; i < m_nodesToDestroy.Count; i++)
  69. {
  70. GUILayout.BeginHorizontal();
  71. EditorGUILayout.LabelField(m_nodesToDestroy[i]);
  72. List<GUIContent> listFbxNames = new List<GUIContent>();
  73. listFbxNames.Add(new GUIContent("[Delete]"));
  74. for (int j = 0; j < m_nodeNameToSuggest.Count; j++)
  75. {
  76. listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j])));
  77. }
  78. options = listFbxNames.ToArray();
  79. selectedNodesToDestroy[i] = EditorGUILayout.Popup(selectedNodesToDestroy[i], options);
  80. GUILayout.EndHorizontal();
  81. }
  82. // List of nodes that will be renamed on the Unity object, unless the user wants to map them or delete them
  83. for (int i = 0; i < m_nodesToRename.Count; i++)
  84. {
  85. GUILayout.BeginHorizontal();
  86. EditorGUILayout.LabelField(m_fbxPrefabUtility.GetUnityObjectName(m_nodesToRename[i]));
  87. List<GUIContent> listFbxNames = new List<GUIContent>();
  88. listFbxNames.Add(new GUIContent("[Delete]"));
  89. for (int j = 0; j < m_nodeNameToSuggest.Count; j++)
  90. {
  91. listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j])));
  92. }
  93. options = listFbxNames.ToArray();
  94. selectedNodesToRename[i] = EditorGUILayout.Popup(selectedNodesToRename[i], options);
  95. GUILayout.EndHorizontal();
  96. }
  97. GUILayout.BeginHorizontal();
  98. if (GUILayout.Button("Apply Changes"))
  99. {
  100. ApplyChanges();
  101. //Close editor window
  102. Close();
  103. }
  104. if (GUILayout.Button("Cancel"))
  105. {
  106. //Close editor window
  107. Close();
  108. }
  109. GUILayout.EndHorizontal();
  110. }
  111. void ApplyChanges()
  112. {
  113. // Nodes to Destroy have Unity names
  114. for (int i = 0; i < m_nodesToDestroy.Count; i++)
  115. {
  116. // != [Delete]
  117. if (selectedNodesToDestroy[i] != 0)
  118. {
  119. StringPair stringpair = new StringPair();
  120. stringpair.FBXObjectName = options[selectedNodesToDestroy[i]].text;
  121. stringpair.UnityObjectName = m_nodesToDestroy[i];
  122. m_fbxPrefab.NameMapping.Add(stringpair);
  123. if (Verbose)
  124. {
  125. Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
  126. }
  127. }
  128. }
  129. // Nodes to Rename have FBX names
  130. for (int i = 0; i < m_nodesToRename.Count; i++)
  131. {
  132. string currentUnityNodeName = m_fbxPrefabUtility.GetUnityObjectName(m_nodesToRename[i]);
  133. // == [Delete]
  134. if (selectedNodesToRename[i] == 0)
  135. {
  136. // Remove previous mapping
  137. m_fbxPrefabUtility.RemoveMappingUnityObjectName(currentUnityNodeName);
  138. }
  139. else
  140. {
  141. if (currentUnityNodeName != m_fbxPrefabUtility.GetUnityObjectName(options[selectedNodesToRename[i]].text))
  142. {
  143. m_fbxPrefabUtility.RemoveMappingUnityObjectName(currentUnityNodeName);
  144. StringPair stringpair = new StringPair();
  145. stringpair.FBXObjectName = options[selectedNodesToRename[i]].text;
  146. stringpair.UnityObjectName = currentUnityNodeName;
  147. m_fbxPrefab.NameMapping.Add(stringpair);
  148. if (Verbose)
  149. {
  150. Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
  151. }
  152. }
  153. else
  154. {
  155. if (Verbose)
  156. {
  157. Debug.Log("ALREADY Mapped Unity: " + currentUnityNodeName + " to FBX: " + options[selectedNodesToRename[i]].text);
  158. }
  159. }
  160. }
  161. }
  162. m_fbxPrefabUtility.SyncPrefab();
  163. }
  164. }
  165. }
  166. #endif // !UNITY_2018_3_OR_NEWER