From e63a34e2bacd03673dcb545b88a0b33f58e0693b Mon Sep 17 00:00:00 2001 From: bd_ Date: Wed, 25 Sep 2024 21:09:58 -0700 Subject: [PATCH] fix: scale adjuster preview destroys proxy renderers inappropriately (#1213) The scale adjuster preview system reparented proxy renderers under proxy bones, in order to handle null root bones and MeshRenderers. However, it then destroyed the entire proxy bone hierarchy, taking all proxy renderers with it. This change instead tracks proxies, and reparents them back to the root to avoid this issue. Closes: #1177 --- Editor/ScaleAdjuster/ScaleAdjusterPreview.cs | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs index 892d20e6..626894c2 100644 --- a/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs +++ b/Editor/ScaleAdjuster/ScaleAdjusterPreview.cs @@ -97,6 +97,8 @@ namespace nadena.dev.modular_avatar.core.editor internal class ScaleAdjusterPreviewNode : IRenderFilterNode { + private readonly HashSet _knownProxies = new(); + private readonly GameObject SourceAvatarRoot; private readonly GameObject VirtualAvatarRoot; @@ -230,6 +232,9 @@ namespace nadena.dev.modular_avatar.core.editor { if (SourceAvatarRoot == null) return Task.FromResult(null); + // Clean any destroyed objects out of _knownProxies to avoid growing this set indefinitely + _knownProxies.RemoveWhere(p => p == null); + var proxyPairList = proxyPairs.ToList(); if (!GetSourceBonesSet(context, proxyPairList).SetEquals(_shadowBoneMap.Keys)) @@ -339,7 +344,15 @@ namespace nadena.dev.modular_avatar.core.editor if (proxy == null) return; var curParent = proxy.transform.parent ?? original.transform.parent; - if (_finalBonesMap.TryGetValue(curParent, out var newRoot)) proxy.transform.SetParent(newRoot, false); + if (_finalBonesMap.TryGetValue(curParent, out var newRoot)) + { + // We need to remember this proxy so we can avoid destroying it when we destroy VirtualAvatarRoot + // in Dispose + + _knownProxies.Add(proxy.transform); + + proxy.transform.SetParent(newRoot, false); + } var smr = proxy as SkinnedMeshRenderer; if (smr == null) return; @@ -351,6 +364,14 @@ namespace nadena.dev.modular_avatar.core.editor public void Dispose() { + foreach (var proxy in _knownProxies) + { + if (proxy != null && proxy.IsChildOf(VirtualAvatarRoot.transform)) + { + proxy.transform.SetParent(null, false); + } + } + Object.DestroyImmediate(VirtualAvatarRoot); _srcBones.Dispose();