Skip to content

Commit f0a5c9d

Browse files
authored
Merge pull request #144 from Unity-Technologies/uni-25526-transform-with-reparenting-is-buggy
UNI-25526: fix a bug with reparenting.
2 parents 8813032 + a02ec4e commit f0a5c9d

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

Assets/FbxExporters/Editor/UnitTests/FbxPrefabTest.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,58 @@ public void TestCubeAtRoot()
380380
// change in behaviour isn't accidental.
381381
Assert.IsNotNull(autoPrefab.GetComponent<BoxCollider>());
382382
}
383+
384+
[Test]
385+
public void TestTransformAndReparenting()
386+
{
387+
// UNI-25526
388+
// We have an fbx with nodes:
389+
// building2 -> building3
390+
// Both have non-identity transforms.
391+
// Then we switch to:
392+
// building2_renamed -> building3
393+
// Joel Fortin noticed that the building3 transform got messed up.
394+
// That's because reparenting changes the transform under the hood.
395+
396+
// Build the original hierarchy and convert it to a prefab.
397+
var root = new GameObject("root");
398+
var building2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
399+
building2.name = "building2";
400+
var building3 = GameObject.CreatePrimitive(PrimitiveType.Cube);
401+
building3.name = "building3";
402+
403+
building2.transform.parent = root.transform;
404+
building2.transform.localScale = new Vector3(2, 2, 2);
405+
building3.transform.parent = building2.transform;
406+
building3.transform.localScale = new Vector3(.5f, .5f, .5f);
407+
408+
var original = FbxExporters.Editor.ConvertToModel.Convert (root,
409+
fbxFullPath: GetRandomFbxFilePath (), keepOriginal: true);
410+
411+
// Make sure it's OK.
412+
Assert.That (original.transform.GetChild (0).name, Is.EqualTo ("building2"));
413+
Assert.That (original.transform.GetChild (0).localScale, Is.EqualTo (new Vector3 (2, 2, 2)));
414+
Assert.That (original.transform.GetChild (0).GetChild (0).name, Is.EqualTo ("building3"));
415+
Assert.That (original.transform.GetChild (0).GetChild (0).localScale, Is.EqualTo (new Vector3 (.5f, .5f, .5f)));
416+
417+
// Modify the hierarchy, export to a new FBX, then copy the FBX under the prefab.
418+
root.SetActive(true);
419+
building2.name = "building2_renamed";
420+
var newCopyPath = FbxExporters.Editor.ModelExporter.ExportObject(
421+
GetRandomFbxFilePath(), root);
422+
SleepForFileTimestamp();
423+
System.IO.File.Copy(
424+
newCopyPath,
425+
original.GetComponent<FbxPrefab>().GetFbxAssetPath(),
426+
overwrite: true);
427+
AssetDatabase.Refresh();
428+
429+
// Make sure the update took.
430+
Assert.That (original.transform.GetChild (0).name, Is.EqualTo ("building2_renamed"));
431+
Assert.That (original.transform.GetChild (0).localScale, Is.EqualTo (new Vector3 (2, 2, 2)));
432+
Assert.That (original.transform.GetChild (0).GetChild (0).name, Is.EqualTo ("building3"));
433+
Assert.That (original.transform.GetChild (0).GetChild (0).localScale, Is.EqualTo (new Vector3 (.5f, .5f, .5f)));
434+
}
383435
}
384436

385437
public class FbxPrefabHelpersTest

Assets/FbxExporters/FbxPrefab.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,12 +686,21 @@ void ClassifyComponents(Transform newFbx, Transform prefab)
686686
for(int i = 0, n = System.Math.Max(oldN, newN); i < n; ++i) {
687687
if (/* isNew */ i < newN) {
688688
var newValue = newValues[i];
689-
if (/* isOld */ i < oldN && oldValues[i] == newValue) {
689+
690+
// Special case on Transform: if we reparented
691+
// this node then always update the transform
692+
// (UNI-25526). That's because when we do the
693+
// reparenting, it changes the 'prefabValue' in
694+
// a complicated way.
695+
var isReparentedTransform = (typename == "UnityEngine.Transform"
696+
&& m_reparentings.ContainsKey(name));
697+
698+
if (/* isOld */ i < oldN && oldValues[i] == newValue && !isReparentedTransform) {
690699
// No change from the old => skip.
691700
continue;
692701
}
693702
if (prefabValues == null) { prefabValues = m_prefab.GetComponentValues(name, typename); }
694-
if (i < prefabValues.Count && prefabValues[i] == newValue) {
703+
if (i < prefabValues.Count && prefabValues[i] == newValue && !isReparentedTransform) {
695704
// Already updated => skip.
696705
continue;
697706
}

0 commit comments

Comments
 (0)