From e0127987aff3758fcccde1e855561b3d6177c87b Mon Sep 17 00:00:00 2001 From: yum Date: Tue, 3 Mar 2026 19:13:06 -0800 Subject: Names are now resolved at build time Lets modules reference each other's meshes without knowing the module's top-level name. --- Scripts/YOTSNDMFGenerator.cs | 48 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'Scripts/YOTSNDMFGenerator.cs') diff --git a/Scripts/YOTSNDMFGenerator.cs b/Scripts/YOTSNDMFGenerator.cs index 4471fa1..8a2faac 100644 --- a/Scripts/YOTSNDMFGenerator.cs +++ b/Scripts/YOTSNDMFGenerator.cs @@ -104,11 +104,14 @@ namespace YOTS descriptor.expressionsMenu = menu; descriptor.expressionParameters = parameters; + // Resolve bare mesh names to full hierarchy paths. + var resolvedJson = ResolveMeshNames(config.jsonConfig, ctx.AvatarRootObject.transform); + // Generate the YOTS animator. RuntimeAnimatorController generatedAnimator = null; try { generatedAnimator = YOTSCore.GenerateAnimator( - config.jsonConfig, + resolvedJson, parameters, menu ); @@ -172,6 +175,49 @@ namespace YOTS public bool skipGeneration; } + // Resolve bare mesh names (no '/') in meshToggles/inverseMeshToggles to all + // matching hierarchy paths. Names containing '/' are kept as explicit paths. + private static string ResolveMeshNames(string jsonConfig, Transform avatarRoot) { + var config = JsonUtility.FromJson(jsonConfig); + var nameToPathsMap = BuildNameToPathsMap(avatarRoot); + foreach (var toggle in config.toggles) { + toggle.meshToggles = ExpandMeshNames(toggle.meshToggles, nameToPathsMap); + toggle.inverseMeshToggles = ExpandMeshNames(toggle.inverseMeshToggles, nameToPathsMap); + } + return JsonUtility.ToJson(config); + } + + private static List ExpandMeshNames(List names, Dictionary> nameToPathsMap) { + if (names == null) return null; + var resolved = new List(); + foreach (var name in names) { + if (name.Contains('/')) { + resolved.Add(name); + } else if (nameToPathsMap.TryGetValue(name, out var paths)) { + resolved.AddRange(paths); + } else { + resolved.Add(name); + } + } + return resolved; + } + + private static Dictionary> BuildNameToPathsMap(Transform root) { + var map = new Dictionary>(); + CollectPaths(root, "", map); + return map; + } + + private static void CollectPaths(Transform current, string currentPath, Dictionary> map) { + foreach (Transform child in current) { + string childPath = currentPath == "" ? child.name : currentPath + "/" + child.name; + if (!map.ContainsKey(child.name)) + map[child.name] = new List(); + map[child.name].Add(childPath); + CollectPaths(child, childPath, map); + } + } + private static VRCExpressionsMenu DeepCopyMenu(VRCExpressionsMenu sourceMenu) { var copiedMenu = UnityEngine.Object.Instantiate(sourceMenu); // Deep copy all submenu references -- cgit v1.2.3