diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs index 791397b22..8fe59c146 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -8,7 +9,7 @@ namespace UniVRM10 /// /// ブレンドシェイプを蓄えてまとめて適用するクラス /// - internal sealed class ExpressionMerger + internal sealed class ExpressionMerger : IDisposable { /// /// Key から Expression を得る @@ -74,5 +75,10 @@ namespace UniVRM10 { m_materialValueBindingMerger.RestoreMaterialInitialValues(); } + + public void Dispose() + { + m_materialValueBindingMerger.Dispose(); + } } } diff --git a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs index 495ccfd90..ee1c75cd9 100644 --- a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs @@ -3,13 +3,14 @@ using System.Collections.Generic; using UniGLTF.Extensions.VRMC_vrm; using UnityEngine; using VRM10.MToon10; +using Object = UnityEngine.Object; namespace UniVRM10 { /// /// Base + (A.Target - Base) * A.Weight + (B.Target - Base) * B.Weight ... /// - internal sealed class MaterialValueBindingMerger + internal sealed class MaterialValueBindingMerger : IDisposable { private static readonly string COLOR_PROPERTY = MToon10Prop.BaseColorFactor.ToUnityShaderLabName(); private static readonly string EMISSION_COLOR_PROPERTY = MToon10Prop.EmissiveFactor.ToUnityShaderLabName(); @@ -18,6 +19,8 @@ namespace UniVRM10 private static readonly string SHADE_COLOR_PROPERTY = MToon10Prop.ShadeColorFactor.ToUnityShaderLabName(); private static readonly string MATCAP_COLOR_PROPERTY = MToon10Prop.MatcapColorFactor.ToUnityShaderLabName(); + private readonly HashSet _clonedMaterials = new(); + public static string GetProperty(MaterialColorType bindType) { switch (bindType) @@ -55,12 +58,24 @@ namespace UniVRM10 Dictionary materialNameMap = new Dictionary(); foreach (var renderer in root.GetComponentsInChildren()) { - foreach (var material in renderer.sharedMaterials) + // VFXRendererなど、Materialが設定できないRendererが存在する + if (renderer is not SkinnedMeshRenderer && renderer is not MeshRenderer) continue; + + var sharedMaterials = renderer.sharedMaterials; + var materials = renderer.materials; + for (var i = 0; i < materials.Length; i++) { - if (material != null && !materialNameMap.ContainsKey(material.name)) - { - materialNameMap.Add(material.name, material); - } + var sharedMaterial = sharedMaterials[i]; + var material = materials[i]; + + if (!sharedMaterial || !material) continue; + + // 複製されたマテリアルはこのクラス内で破棄 + if (sharedMaterial != material) _clonedMaterials.Add(material); + + // 複製前の名前を記録しておく + // なお、Vrm10Runtimeのインスタンスが作られるより先にユーザーによってMaterialが複製されるパターンは想定しない + materialNameMap.TryAdd(sharedMaterial.name, material); } } @@ -288,5 +303,14 @@ namespace UniVRM10 { InitializeMaterialMap(clipMap, root); } + + public void Dispose() + { + foreach (var clonedMaterial in _clonedMaterials) + { + Object.Destroy(clonedMaterial); + } + _clonedMaterials.Clear(); + } } }