Skip to content

Commit 853eb64

Browse files
authored
Merge pull request #295 from Unity-Technologies/Uni-36061-GraphView-UI-Remapping
Uni 36061 graph view ui remapping
2 parents a9baf82 + a8b43dc commit 853eb64

File tree

5 files changed

+309
-21
lines changed

5 files changed

+309
-21
lines changed

Assets/FbxExporters/Editor/FbxPrefabAutoUpdater.cs

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,6 @@ public static bool OnValidateMenuItem()
222222
}
223223

224224

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-
233225
/// <summary>
234226
/// Launch the manual update of the linked prefab specified
235227
/// </summary>
@@ -262,7 +254,7 @@ public FbxPrefabUtility(FbxPrefab fbxPrefab){
262254
public string GetUnityObjectName(string fbxObjectName)
263255
{
264256
string newNameInUnity = fbxObjectName;
265-
if (String.IsNullOrEmpty(fbxObjectName) && m_fbxPrefab.NameMapping != null) {
257+
if (!String.IsNullOrEmpty(fbxObjectName) && m_fbxPrefab.NameMapping != null) {
266258
foreach (var nameMapping in m_fbxPrefab.NameMapping) {
267259
if (fbxObjectName == nameMapping.FBXObjectName) {
268260
newNameInUnity = nameMapping.UnityObjectName;
@@ -272,13 +264,64 @@ public string GetUnityObjectName(string fbxObjectName)
272264
}
273265
return newNameInUnity;
274266
}
267+
268+
/// <summary>
269+
/// Utility function: remove the name mapping matching the unity name specified
270+
/// </summary>
271+
public void RemoveMappingFBXObjectName(string fbxObjectName)
272+
{
273+
FbxPrefab.StringPair stockNameMapping = new FbxPrefab.StringPair();
274+
if (!String.IsNullOrEmpty(fbxObjectName) && m_fbxPrefab.NameMapping != null)
275+
{
276+
bool foundMapping = false;
277+
foreach (FbxPrefab.StringPair nameMapping in m_fbxPrefab.NameMapping)
278+
{
279+
if (fbxObjectName == nameMapping.FBXObjectName)
280+
{
281+
stockNameMapping = nameMapping;
282+
foundMapping = true;
283+
break;
284+
}
285+
}
286+
if (foundMapping)
287+
{
288+
m_fbxPrefab.NameMapping.Remove(stockNameMapping);
289+
}
290+
}
291+
}
292+
293+
/// <summary>
294+
/// Utility function: remove the name mapping matching the FBX name specified
295+
/// </summary>
296+
public void RemoveMappingUnityObjectName(string unityObjectName)
297+
{
298+
FbxPrefab.StringPair stockNameMapping = new FbxPrefab.StringPair();
299+
if (!String.IsNullOrEmpty(unityObjectName) && m_fbxPrefab.NameMapping != null)
300+
{
301+
bool foundMapping = false;
302+
foreach (FbxPrefab.StringPair nameMapping in m_fbxPrefab.NameMapping)
303+
{
304+
if (unityObjectName == nameMapping.UnityObjectName)
305+
{
306+
stockNameMapping = nameMapping;
307+
foundMapping = true;
308+
break;
309+
}
310+
}
311+
if (foundMapping)
312+
{
313+
m_fbxPrefab.NameMapping.Remove(stockNameMapping);
314+
}
315+
}
316+
}
317+
275318
/// <summary>
276319
/// Utility function: check if the user has specified a matching FBX name in the inspector
277320
/// </summary>
278321
public string GetFBXObjectName(string unityObjectName)
279322
{
280323
string oldNameInFBX = unityObjectName;
281-
if (String.IsNullOrEmpty(unityObjectName) && m_fbxPrefab.NameMapping != null) {
324+
if (!String.IsNullOrEmpty(unityObjectName) && m_fbxPrefab.NameMapping != null) {
282325
foreach (var nameMapping in m_fbxPrefab.NameMapping) {
283326
if (unityObjectName == nameMapping.UnityObjectName) {
284327
oldNameInFBX = nameMapping.FBXObjectName;
@@ -1039,6 +1082,21 @@ public bool NeedsUpdates() {
10391082
;
10401083
}
10411084

1085+
public HashSet<String> GetNodesToCreate()
1086+
{
1087+
return m_nodesToCreate;
1088+
}
1089+
1090+
public HashSet<String> GetNodesToDestroy()
1091+
{
1092+
return m_nodesToDestroy;
1093+
}
1094+
1095+
public HashSet<String> GetNodesToRename()
1096+
{
1097+
return m_nodesToRename;
1098+
}
1099+
10421100
/// <summary>
10431101
/// Then we act -- in a slightly different order:
10441102
/// 1. Create all the new nodes we need to create.
@@ -1082,12 +1140,28 @@ public HashSet<GameObject> ImplementUpdates(FbxPrefab prefabInstance)
10821140
updatedNodes.Add(newNode);
10831141
}
10841142

1143+
1144+
// Rename old nodes (unity names) into new nodes (FBX names).
1145+
// We do it before the reparenting because m_reparentings contains the fbx name and won't find the parent without the renaming
1146+
foreach (var FBXNodeNameToRename in m_nodesToRename)
1147+
{
1148+
if (prefabNodes[m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename)] != null)
1149+
{
1150+
prefabNodes[m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename)].name = FBXNodeNameToRename;
1151+
1152+
Transform stockTransform = prefabNodes[m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename)];
1153+
prefabNodes.Remove(m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename));
1154+
prefabNodes.Add(FBXNodeNameToRename, stockTransform);
1155+
Log("Renamed {0} into {1}", m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename), FBXNodeNameToRename);
1156+
}
1157+
}
1158+
10851159
// Implement the reparenting in two phases to avoid making loops, e.g.
10861160
// if we're flipping from a -> b to b -> a, we don't want to
10871161
// have a->b->a in the intermediate stage.
10881162

10891163
// First set the parents to null.
1090-
foreach(var kvp in m_reparentings) {
1164+
foreach (var kvp in m_reparentings) {
10911165
var name = kvp.Key;
10921166
prefabNodes[name].parent = null;
10931167
}
@@ -1136,17 +1210,12 @@ public HashSet<GameObject> ImplementUpdates(FbxPrefab prefabInstance)
11361210
}
11371211
}
11381212
}
1139-
1140-
// Rename old nodes (unity names) into new nodes (FBX names).
1141-
foreach (var FBXNodeNameToRename in m_nodesToRename)
1142-
{
1143-
prefabNodes[m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename)].name = FBXNodeNameToRename;
1144-
Log("Renamed {0} into {1}", m_fbxPrefabUtility.GetUnityObjectName(FBXNodeNameToRename), FBXNodeNameToRename);
1145-
}
11461213

11471214
// Create or update the new components.
11481215
foreach (var kvp in m_componentsToUpdate) {
11491216
var componentName = kvp.Key;
1217+
// 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
1218+
componentName = m_fbxPrefabUtility.GetFBXObjectName(componentName);
11501219
Debug.Log("Component: " + componentName);
11511220
var fbxComponents = kvp.Value;
11521221
var prefabXfo = prefabNodes[componentName];

Assets/FbxExporters/Editor/FbxPrefabInspector.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public override void OnInspectorGUI() {
1717
EditorGUILayout.HelpBox("Please select a prefab. You can't edit an instance in the scene.",
1818
MessageType.Info);
1919
}
20-
EditorGUI.BeginDisabledGroup(isDisabled);
2120

22-
var fbxPrefabUtility = new FbxPrefabAutoUpdater.FbxPrefabUtility (fbxPrefab);
21+
EditorGUI.BeginDisabledGroup(isDisabled);
22+
FbxPrefabAutoUpdater.FbxPrefabUtility fbxPrefabUtility = new FbxPrefabAutoUpdater.FbxPrefabUtility (fbxPrefab);
2323
var oldFbxAsset = fbxPrefabUtility.GetFbxAsset();
2424
var newFbxAsset = EditorGUILayout.ObjectField(new GUIContent("Source Fbx Asset", "The FBX file that is linked to this Prefab"), oldFbxAsset,
2525
typeof(GameObject), allowSceneObjects: false) as GameObject;
@@ -28,12 +28,19 @@ public override void OnInspectorGUI() {
2828
} else if (newFbxAsset != oldFbxAsset) {
2929
fbxPrefabUtility.SetSourceModel(newFbxAsset);
3030
}
31-
3231
EditorGUI.EndDisabledGroup();
3332

3433
EditorGUILayout.PropertyField(m_GameObjectProp, true);
3534

3635
#if FBXEXPORTER_DEBUG
36+
if (GUILayout.Button("Update prefab manually..."))
37+
{
38+
// Get existing open window or if none, make a new one:
39+
ManualUpdateEditorWindow window = (ManualUpdateEditorWindow)EditorWindow.GetWindow(typeof(ManualUpdateEditorWindow));
40+
window.Init(fbxPrefabUtility, fbxPrefab);
41+
window.Show();
42+
}
43+
3744
EditorGUILayout.LabelField ("Debug info:");
3845
try {
3946
fbxPrefabUtility.GetFbxHistory().ToJson();
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
using UnityEngine;
2+
using UnityEditor;
3+
using System.Collections.Generic;
4+
using FbxExporters;
5+
using System.Linq;
6+
7+
public class ManualUpdateEditorWindow : EditorWindow
8+
{
9+
int[] selectedNodesToDestroy;
10+
int[] selectedNodesToRename;
11+
12+
FbxPrefabAutoUpdater.FbxPrefabUtility m_fbxPrefabUtility;
13+
FbxPrefab m_fbxPrefab;
14+
GUIContent[] options;
15+
List<string> m_nodesToCreate;
16+
List<string> m_nodesToDestroy;
17+
List<string> m_nodesToRename;
18+
19+
List<string> m_nodeNameToSuggest;
20+
21+
public void Init(FbxPrefabAutoUpdater.FbxPrefabUtility fbxPrefabUtility, FbxPrefab fbxPrefab)
22+
{
23+
FbxPrefabAutoUpdater.FbxPrefabUtility.UpdateList updates = new FbxPrefabAutoUpdater.FbxPrefabUtility.UpdateList(new FbxPrefabAutoUpdater.FbxPrefabUtility.FbxRepresentation(fbxPrefab.FbxHistory), fbxPrefab.FbxModel.transform, fbxPrefab);
24+
25+
m_fbxPrefabUtility = fbxPrefabUtility;
26+
m_fbxPrefab = fbxPrefab;
27+
// Convert Hashset into List
28+
m_nodesToCreate = updates.GetNodesToCreate().ToList();
29+
m_nodesToDestroy = updates.GetNodesToDestroy().ToList();
30+
m_nodesToRename = updates.GetNodesToRename().ToList();
31+
// Create the dropdown list
32+
m_nodeNameToSuggest = new List<string>();
33+
m_nodeNameToSuggest.AddRange(m_nodesToCreate);
34+
m_nodeNameToSuggest.AddRange(m_nodesToRename);
35+
36+
// Add extra 1 for the [Delete] option
37+
selectedNodesToDestroy = new int[m_nodeNameToSuggest.Count + 1];
38+
selectedNodesToRename = new int[m_nodeNameToSuggest.Count + 1];
39+
40+
// Default option for nodes to rename. Shows the current name mapping
41+
for (int i = 0; i < m_nodesToRename.Count; i++)
42+
{
43+
for (int j = 0; j < m_nodeNameToSuggest.Count; j++)
44+
{
45+
if (m_nodeNameToSuggest[j] == m_nodesToRename[i])
46+
{
47+
// Add extra 1 for the [Delete] option
48+
selectedNodesToRename[i] = j + 1;
49+
}
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+
63+
//Titles of the columns
64+
GUILayout.BeginHorizontal();
65+
GUILayout.Label("Unity Names", EditorStyles.boldLabel);
66+
GUILayout.Label("FBX Names", EditorStyles.boldLabel);
67+
GUILayout.EndHorizontal();
68+
69+
// List of nodes that will be destroyed on the Unity object, unless the user wants to map them
70+
for (int i = 0; i < m_nodesToDestroy.Count; i++)
71+
{
72+
GUILayout.BeginHorizontal();
73+
EditorGUILayout.LabelField(m_nodesToDestroy[i]);
74+
75+
List<GUIContent> listFbxNames = new List<GUIContent>();
76+
listFbxNames.Add(new GUIContent("[Delete]"));
77+
78+
for(int j = 0; j < m_nodeNameToSuggest.Count; j++)
79+
{
80+
listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j])));
81+
}
82+
83+
options = listFbxNames.ToArray();
84+
selectedNodesToDestroy[i] = EditorGUILayout.Popup(selectedNodesToDestroy[i], options);
85+
86+
GUILayout.EndHorizontal();
87+
}
88+
89+
// List of nodes that will be renamed on the Unity object, unless the user wants to map them or delete them
90+
for (int i = 0; i < m_nodesToRename.Count; i++)
91+
{
92+
GUILayout.BeginHorizontal();
93+
EditorGUILayout.LabelField(m_fbxPrefabUtility.GetUnityObjectName(m_nodesToRename[i]));
94+
95+
List<GUIContent> listFbxNames = new List<GUIContent>();
96+
listFbxNames.Add(new GUIContent("[Delete]"));
97+
98+
for (int j = 0; j < m_nodeNameToSuggest.Count; j++)
99+
{
100+
listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j])));
101+
}
102+
103+
options = listFbxNames.ToArray();
104+
105+
selectedNodesToRename[i] = EditorGUILayout.Popup(selectedNodesToRename[i], options);
106+
107+
GUILayout.EndHorizontal();
108+
}
109+
110+
GUILayout.BeginHorizontal();
111+
112+
if (GUILayout.Button("Apply Changes"))
113+
{
114+
ApplyChanges();
115+
//Close editor window
116+
Close();
117+
}
118+
119+
if (GUILayout.Button("Cancel"))
120+
{
121+
//Close editor window
122+
Close();
123+
}
124+
GUILayout.EndHorizontal();
125+
}
126+
127+
void ApplyChanges()
128+
{
129+
// Nodes to Destroy have Unity names
130+
for (int i = 0; i < m_nodesToDestroy.Count; i++)
131+
{
132+
// != [Delete]
133+
if (selectedNodesToDestroy[i] != 0)
134+
{
135+
FbxPrefab.StringPair stringpair = new FbxPrefab.StringPair();
136+
stringpair.FBXObjectName = options[selectedNodesToDestroy[i]].text;
137+
stringpair.UnityObjectName = m_nodesToDestroy[i];
138+
139+
m_fbxPrefab.NameMapping.Add(stringpair);
140+
Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
141+
}
142+
}
143+
144+
// Nodes to Rename have FBX names
145+
for (int i = 0; i < m_nodesToRename.Count; i++)
146+
{
147+
string currentUnityNodeName = m_fbxPrefabUtility.GetUnityObjectName(m_nodesToRename[i]);
148+
// == [Delete]
149+
if (selectedNodesToRename[i] == 0)
150+
{
151+
// Remove previous mapping
152+
m_fbxPrefabUtility.RemoveMappingUnityObjectName(currentUnityNodeName);
153+
}
154+
else
155+
{
156+
if (currentUnityNodeName != m_fbxPrefabUtility.GetUnityObjectName(options[selectedNodesToRename[i]].text))
157+
{
158+
m_fbxPrefabUtility.RemoveMappingUnityObjectName(currentUnityNodeName);
159+
FbxPrefab.StringPair stringpair = new FbxPrefab.StringPair();
160+
stringpair.FBXObjectName = options[selectedNodesToRename[i]].text;
161+
stringpair.UnityObjectName = currentUnityNodeName;
162+
m_fbxPrefab.NameMapping.Add(stringpair);
163+
164+
Debug.Log("Mapped Unity: " + stringpair.UnityObjectName + " to FBX: " + stringpair.FBXObjectName);
165+
}
166+
else
167+
{
168+
Debug.Log("ALREADY Mapped Unity: " + currentUnityNodeName + " to FBX: " + options[selectedNodesToRename[i]].text);
169+
}
170+
}
171+
}
172+
173+
m_fbxPrefabUtility.SyncPrefab();
174+
}
175+
}

Assets/FbxExporters/Editor/ManualUpdateEditorWindow.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)