diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs b/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs deleted file mode 100644 index 01cd96de..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEditor.IMGUI.Controls; -using UnityEngine; -using VRC.SDK3.Avatars.Components; - -namespace nadena.dev.modular_avatar.core.editor { - public class AvMenuFolderCreatorTreeViewWindow : EditorWindow { - private AvMenuFolderCreatorTreeView _treeView; - - private VRCAvatarDescriptor Avatar { - set => this._treeView.Avatar = value; - } - - private ModularAvatarSubMenuCreator Creator { - set => this._treeView.Creator = value; - } - - private Action OnMenuSelected = (creator) => { }; - - private void Awake() { - this._treeView = new AvMenuFolderCreatorTreeView(new TreeViewState()) { - OnSelect = (creator) => this.OnMenuSelected.Invoke(creator), - onDoubleClickSelect = this.Close - }; - } - - private void OnLostFocus() { - this.Close(); - } - - private void OnDisable() { - this.OnMenuSelected = (creator) => { }; - } - - private void OnGUI() { - if (this._treeView == null || this._treeView.Avatar == null) { - this.Close(); - return; - } - - this._treeView.OnGUI(new Rect(0, 0, this.position.width, this.position.height)); - } - - internal static void Show(VRCAvatarDescriptor avatar, ModularAvatarSubMenuCreator creator, Action OnSelect) { - AvMenuFolderCreatorTreeViewWindow window = GetWindow(); - window.titleContent = new GUIContent("Select menu folder creator"); - - window.Avatar = avatar; - window.Creator = creator; - window.OnMenuSelected = OnSelect; - - window.Show(); - } - } - - public class AvMenuFolderCreatorTreeView : TreeView { - private VRCAvatarDescriptor _avatar; - public VRCAvatarDescriptor Avatar { - get => this._avatar; - set { - this._avatar = value; - this.Reload(); - } - } - - private ModularAvatarSubMenuCreator _creator; - public ModularAvatarSubMenuCreator Creator { - get => this._creator; - set { - this._creator = value; - this.Reload(); - } - } - - private int _currentCreatorIndex; - private readonly Texture2D _currentBackgroundTexture; - - internal Action OnSelect = (creator) => { }; - internal Action onDoubleClickSelect = () => { }; - - private readonly List _creatorItems = new List(); - private readonly HashSet _visitedCreators = new HashSet(); - - private Dictionary> _childMap; - private List _rootCreators; - - public AvMenuFolderCreatorTreeView(TreeViewState state) : base(state) { - this._currentBackgroundTexture = new Texture2D(1, 1); - this._currentBackgroundTexture.SetPixel(0, 0, new Color(0.0f, 0.3f, 0.0f)); - this._currentBackgroundTexture.Apply(); - } - - protected override void SelectionChanged(IList selectedIds) { - if (selectedIds[0] == this._currentCreatorIndex) return; - this.OnSelect.Invoke(this._creatorItems[selectedIds[0]]); - this.Reload(); - } - - protected override void DoubleClickedItem(int id) { - if (id == this._currentCreatorIndex) return; - this.OnSelect.Invoke(this._creatorItems[id]); - this.onDoubleClickSelect.Invoke(); - } - - protected override TreeViewItem BuildRoot() { - this._creatorItems.Clear(); - this._visitedCreators.Clear(); - this._currentCreatorIndex = -1; - this.MappingFolderCreator(); - - TreeViewItem root = new TreeViewItem(-1, -1, ""); - List treeItems = new List(); - treeItems.Add(new TreeViewItem { - id = treeItems.Count, - depth = 0, - displayName = $"{this._avatar.name} ({(this._avatar.expressionsMenu != null ? this._avatar.expressionsMenu.name : null)})" - }); - this._creatorItems.Add(null); - - foreach (ModularAvatarSubMenuCreator rootCreator in this._rootCreators) { - bool isCurrent = rootCreator == this.Creator; - if (isCurrent) { - this._currentCreatorIndex = treeItems.Count; - } - treeItems.Add(new TreeViewItem { - id = treeItems.Count, - depth = 1, - displayName = isCurrent ? "This" : $"{rootCreator.name} ({rootCreator.folderName})" - }); - this._creatorItems.Add(rootCreator); - this._visitedCreators.Add(rootCreator); - if (isCurrent) continue; - this.TraverseCreator(2, treeItems, rootCreator); - } - - SetupParentsAndChildrenFromDepths(root, treeItems); - return root; - } - - private void TraverseCreator(int depth, List items, ModularAvatarSubMenuCreator creator) { - if (!this._childMap.TryGetValue(creator, out List children)) return; - foreach (ModularAvatarSubMenuCreator child in children.Where(child => !this._visitedCreators.Contains(child))) { - bool isCurrent = child == this.Creator; - if (isCurrent) { - this._currentCreatorIndex = items.Count; - } - - items.Add(new TreeViewItem { - id = items.Count, - depth = depth, - displayName = isCurrent ? "This" : $"{child.name} ({child.folderName})" - }); - - this._creatorItems.Add(child); - this._visitedCreators.Add(child); - if (isCurrent) continue; - this.TraverseCreator(depth + 1, items, child); - } - } - - protected override void RowGUI(RowGUIArgs args) { - if (args.item.id == this._currentCreatorIndex) { - Rect backGroundRect = args.rowRect; - GUI.DrawTexture(backGroundRect, this._currentBackgroundTexture, ScaleMode.StretchToFill, false, 0); - } - - base.RowGUI(args); - } - - - private void MappingFolderCreator() { - this._childMap = new Dictionary>(); - this._rootCreators = new List(); - - foreach (ModularAvatarSubMenuCreator creator in this.Avatar.gameObject.GetComponentsInChildren()) { - if (!creator.enabled) continue; - if (creator.installTargetType == ModularAvatarSubMenuCreator.InstallTargetType.VRCExpressionMenu) { - this._rootCreators.Add(creator); - } else { - if (creator.installTargetCreator == null) { - this._rootCreators.Add(creator); - } else { - if (!this._childMap.TryGetValue(creator.installTargetCreator, out List children)) { - children = new List(); - this._childMap[creator.installTargetCreator] = children; - } - - children.Add(creator); - } - } - } - } - } -} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs.meta b/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs.meta deleted file mode 100644 index ed02d29a..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/AvMenuFolderCreatorTreeViewWindow.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 8947dd0003544292b4fa12250f5771c9 -timeCreated: 1669814530 \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/MenuInstallerEditor.cs b/Packages/nadena.dev.modular-avatar/Editor/Inspector/MenuInstallerEditor.cs index 02eb38dd..f7ca7bcc 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/MenuInstallerEditor.cs +++ b/Packages/nadena.dev.modular-avatar/Editor/Inspector/MenuInstallerEditor.cs @@ -7,8 +7,6 @@ using VRC.SDK3.Avatars.Components; using VRC.SDK3.Avatars.ScriptableObjects; using static nadena.dev.modular_avatar.core.editor.Localization; using static nadena.dev.modular_avatar.core.editor.Util; -using static nadena.dev.modular_avatar.core.ModularAvatarSubMenuCreator; -using Object = UnityEngine.Object; namespace nadena.dev.modular_avatar.core.editor { @@ -24,7 +22,6 @@ namespace nadena.dev.modular_avatar.core.editor private bool _devFoldout; private HashSet _avatarMenus; - private HashSet _menuFolderCreators; private Dictionary> _menuInstallersMap; @@ -34,7 +31,6 @@ namespace nadena.dev.modular_avatar.core.editor FindMenus(); FindMenuInstallers(); - FindMenuFolderCreators(); } private void SetupMenuEditor() @@ -58,51 +54,55 @@ namespace nadena.dev.modular_avatar.core.editor protected override void OnInnerInspectorGUI() { SetupMenuEditor(); - + + var installTo = serializedObject.FindProperty(nameof(ModularAvatarMenuInstaller.installTargetMenu)); + + var isEnabled = targets.Length != 1 || ((ModularAvatarMenuInstaller) target).enabled; + VRCAvatarDescriptor commonAvatar = FindCommonAvatar(); - SerializedProperty installTargetTypeProperty = serializedObject.FindProperty(nameof(ModularAvatarMenuInstaller.InstallTargetType)); - EditorGUILayout.PropertyField(installTargetTypeProperty, new GUIContent("Install Target Type")); - InstallTargetType installTargetType = (InstallTargetType)Enum.ToObject(typeof(InstallTargetType), installTargetTypeProperty.enumValueIndex); - - if (!installTargetTypeProperty.hasMultipleDifferentValues) + if (!installTo.hasMultipleDifferentValues) { - string installTargetMenuPropertyName; - Type installTargetObjectType; - if (installTargetType == InstallTargetType.VRCExpressionMenu) + if (installTo.objectReferenceValue == null) { - installTargetMenuPropertyName = nameof(ModularAvatarSubMenuCreator.installTargetMenu); - installTargetObjectType = typeof(VRCExpressionsMenu); - } else - { - installTargetMenuPropertyName = nameof(ModularAvatarSubMenuCreator.installTargetCreator); - installTargetObjectType = typeof(ModularAvatarSubMenuCreator); - commonAvatar = null; - } - - SerializedProperty installTargetProperty = this.serializedObject.FindProperty(installTargetMenuPropertyName); - this.ShowMenuInstallerHelpBox(installTargetProperty, installTargetType); - this.ShowInstallTargetPropertyField(installTargetProperty, commonAvatar, installTargetObjectType); - - var avatar = RuntimeUtil.FindAvatarInParents(_installer.transform); - if (avatar != null && GUILayout.Button(G("menuinstall.selectmenu"))) - { - if (installTargetType == InstallTargetType.VRCExpressionMenu) + if (isEnabled) { - AvMenuTreeViewWindow.Show(avatar, _installer, menu => - { - installTargetProperty.objectReferenceValue = menu; - serializedObject.ApplyModifiedProperties(); - }); - } else { - AvMenuFolderCreatorTreeViewWindow.Show(avatar, null, creator => - { - installTargetProperty.objectReferenceValue = creator; - serializedObject.ApplyModifiedProperties(); - }); + EditorGUILayout.HelpBox(S("menuinstall.help.hint_set_menu"), MessageType.Info); } } - + else if (!IsMenuReachable(RuntimeUtil.FindAvatarInParents(((Component) target).transform), + (VRCExpressionsMenu) installTo.objectReferenceValue)) + { + EditorGUILayout.HelpBox(S("menuinstall.help.hint_bad_menu"), MessageType.Error); + } + } + + if (installTo.hasMultipleDifferentValues || commonAvatar == null) + { + EditorGUILayout.PropertyField(installTo, G("menuinstall.installto")); + } + else + { + var displayValue = installTo.objectReferenceValue; + if (displayValue == null) displayValue = commonAvatar.expressionsMenu; + + EditorGUI.BeginChangeCheck(); + var newValue = EditorGUILayout.ObjectField(G("menuinstall.installto"), displayValue, + typeof(VRCExpressionsMenu), false); + if (EditorGUI.EndChangeCheck()) + { + installTo.objectReferenceValue = newValue; + } + } + + var avatar = RuntimeUtil.FindAvatarInParents(_installer.transform); + if (avatar != null && GUILayout.Button(G("menuinstall.selectmenu"))) + { + AvMenuTreeViewWindow.Show(avatar, _installer, menu => + { + installTo.objectReferenceValue = menu; + serializedObject.ApplyModifiedProperties(); + }); } if (targets.Length == 1) @@ -149,56 +149,6 @@ namespace nadena.dev.modular_avatar.core.editor Localization.ShowLanguageUI(); } - - private void ShowMenuInstallerHelpBox(SerializedProperty installTargetProperty, InstallTargetType installTargetType) - { - if (installTargetProperty.hasMultipleDifferentValues) return; - bool isEnabled = targets.Length != 1 || this._installer.enabled; - - if (installTargetProperty.objectReferenceValue == null) - { - if (!isEnabled) return; - EditorGUILayout.HelpBox(S("menuinstall.help.hint_set_menu"), MessageType.Info); - } - else - { - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._installer.transform); - switch (installTargetType) - { - case InstallTargetType.VRCExpressionMenu: - if (!this.IsMenuReachable(avatar, (VRCExpressionsMenu)installTargetProperty.objectReferenceValue)) - { - EditorGUILayout.HelpBox(Localization.S("menuinstall.help.hint_bad_menu"), MessageType.Error); - } - break; - case InstallTargetType.FolderCreator: - if (!this.IsMenuReachable(avatar, (ModularAvatarSubMenuCreator)installTargetProperty.objectReferenceValue, new HashSet())) - { - EditorGUILayout.HelpBox("選択されたメニューフォルダからアバターまでのパスが見つかりません。", MessageType.Error); - } - break; - default: - throw new ArgumentOutOfRangeException(nameof(installTargetType), installTargetType, null); - } - } - } - - private void ShowInstallTargetPropertyField(SerializedProperty installTargetProperty, VRCAvatarDescriptor avatar, Type propertyType) - { - Object displayValue = installTargetProperty.objectReferenceValue; - if (!installTargetProperty.hasMultipleDifferentValues && avatar != null) - { - if (displayValue == null) displayValue = avatar.expressionsMenu; - } - - EditorGUI.BeginChangeCheck(); - Object newValue = EditorGUILayout.ObjectField(G("menuinstall.installto"), displayValue, propertyType, - propertyType == typeof(ModularAvatarSubMenuCreator)); - if (EditorGUI.EndChangeCheck()) - { - installTargetProperty.objectReferenceValue = newValue; - } - } private VRCAvatarDescriptor FindCommonAvatar() { @@ -295,23 +245,6 @@ namespace nadena.dev.modular_avatar.core.editor } } - private void FindMenuFolderCreators() - { - if (this.targets.Length > 1) - { - this._menuFolderCreators = null; - return; - } - - this._menuFolderCreators = new HashSet(); - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._installer.transform); - if (avatar == null) return; - foreach (ModularAvatarSubMenuCreator creator in avatar.gameObject.GetComponentsInChildren()) - { - this._menuFolderCreators.Add(creator); - } - } - private bool IsMenuReachable(VRCAvatarDescriptor avatar, VRCExpressionsMenu menu, HashSet visitedInstaller = null) { if (_avatarMenus == null || _avatarMenus.Contains(menu)) return true; diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs b/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs deleted file mode 100644 index 8c5d50ce..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using VRC.SDK3.Avatars.Components; -using VRC.SDK3.Avatars.ScriptableObjects; -using static nadena.dev.modular_avatar.core.ModularAvatarSubMenuCreator; -using Object = UnityEngine.Object; - -namespace nadena.dev.modular_avatar.core.editor { - [CustomEditor(typeof(ModularAvatarSubMenuCreator))] - [CanEditMultipleObjects] - internal class SubMenuCreatorEditor : MAEditorBase { - private ModularAvatarSubMenuCreator _creator; - private HashSet _avatarMenus; - private HashSet _menuFolderCreators; - - private void OnEnable() { - this._creator = (ModularAvatarSubMenuCreator)this.target; - this.FindMenus(); - this.FindMenuFolderCreators(); - } - - protected override void OnInnerInspectorGUI() { - VRCAvatarDescriptor commonAvatar = this.FindCommonAvatar(); - - SerializedProperty installTargetTypeProperty = this.serializedObject.FindProperty(nameof(ModularAvatarSubMenuCreator.installTargetType)); - EditorGUILayout.PropertyField(installTargetTypeProperty, new GUIContent("Install Target Type")); - InstallTargetType installTargetType = (InstallTargetType)Enum.ToObject(typeof(InstallTargetType), installTargetTypeProperty.enumValueIndex); - - if (!installTargetTypeProperty.hasMultipleDifferentValues) { - string installTargetMenuPropertyName; - Type installTargetObjectType; - if (installTargetType == InstallTargetType.VRCExpressionMenu) { - installTargetMenuPropertyName = nameof(ModularAvatarSubMenuCreator.installTargetMenu); - installTargetObjectType = typeof(VRCExpressionsMenu); - } else { - installTargetMenuPropertyName = nameof(ModularAvatarSubMenuCreator.installTargetCreator); - installTargetObjectType = typeof(ModularAvatarSubMenuCreator); - commonAvatar = null; - } - - SerializedProperty installTargetProperty = this.serializedObject.FindProperty(installTargetMenuPropertyName); - this.ShowMenuFolderCreateHelpBox(installTargetProperty, installTargetType); - this.ShowInstallTargetPropertyField(installTargetProperty, commonAvatar, installTargetObjectType); - - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform); - if (avatar != null && GUILayout.Button(Localization.G("menuinstall.selectmenu"))) { - if (installTargetType == InstallTargetType.VRCExpressionMenu) { - AvMenuTreeViewWindow.Show(avatar, null, menu => { - installTargetProperty.objectReferenceValue = menu; - serializedObject.ApplyModifiedProperties(); - }); - } else { - AvMenuFolderCreatorTreeViewWindow.Show(avatar, this._creator, creator => { - installTargetProperty.objectReferenceValue = creator; - serializedObject.ApplyModifiedProperties(); - }); - } - } - } - - SerializedProperty folderNameProperty = this.serializedObject.FindProperty(nameof(ModularAvatarSubMenuCreator.folderName)); - EditorGUILayout.PropertyField(folderNameProperty, new GUIContent("Folder Name")); - - SerializedProperty iconProperty = this.serializedObject.FindProperty(nameof(ModularAvatarSubMenuCreator.icon)); - EditorGUILayout.PropertyField(iconProperty, new GUIContent("Folder Icon")); - - serializedObject.ApplyModifiedProperties(); - Localization.ShowLanguageUI(); - } - - private void ShowMenuFolderCreateHelpBox(SerializedProperty installTargetProperty, InstallTargetType installTargetType) { - if (installTargetProperty.hasMultipleDifferentValues) return; - bool isEnabled = this.targets.Length != 1 || this._creator.enabled; - - if (installTargetProperty.objectReferenceValue == null) { - if (!isEnabled) return; - EditorGUILayout.HelpBox(Localization.S("menuinstall.help.hint_set_menu"), MessageType.Info); - } else { - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform); - switch (installTargetType) { - case InstallTargetType.VRCExpressionMenu: - if (!this.IsMenuReachable(avatar, (VRCExpressionsMenu)installTargetProperty.objectReferenceValue)) { - EditorGUILayout.HelpBox(Localization.S("menuinstall.help.hint_bad_menu"), MessageType.Error); - } - - break; - case InstallTargetType.FolderCreator: - if (!this.IsMenuReachable(avatar, (ModularAvatarSubMenuCreator)installTargetProperty.objectReferenceValue, - new HashSet())) { - EditorGUILayout.HelpBox("選択されたメニューフォルダからアバターまでのパスが見つかりません。", MessageType.Error); - } - - break; - default: - throw new ArgumentOutOfRangeException(nameof(installTargetType), installTargetType, null); - } - } - } - - private void ShowInstallTargetPropertyField(SerializedProperty installTargetProperty, VRCAvatarDescriptor avatar, Type propertyType) { - Object displayValue = installTargetProperty.objectReferenceValue; - if (!installTargetProperty.hasMultipleDifferentValues && avatar != null) { - if (displayValue == null) displayValue = avatar.expressionsMenu; - } - - EditorGUI.BeginChangeCheck(); - Object newValue = EditorGUILayout.ObjectField(Localization.G("menuinstall.installto"), displayValue, propertyType, - propertyType == typeof(ModularAvatarSubMenuCreator)); - if (newValue == this._creator) newValue = displayValue; - if (EditorGUI.EndChangeCheck()) { - installTargetProperty.objectReferenceValue = newValue; - } - } - - private VRCAvatarDescriptor FindCommonAvatar() { - VRCAvatarDescriptor commonAvatar = null; - foreach (Object targetObject in targets) { - ModularAvatarSubMenuCreator component = (ModularAvatarSubMenuCreator)targetObject; - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(component.transform); - if (avatar == null) return null; - - if (commonAvatar == null) { - commonAvatar = avatar; - } else if (commonAvatar != avatar) { - return null; - } - } - - return commonAvatar; - } - - private void FindMenus() { - if (this.targets.Length > 1) { - this._avatarMenus = null; - return; - } - - this._avatarMenus = new HashSet(); - Queue queue = new Queue(); - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform); - if (avatar == null || avatar.expressionsMenu == null) return; - queue.Enqueue(avatar.expressionsMenu); - - while (queue.Count > 0) { - var menu = queue.Dequeue(); - if (this._avatarMenus.Contains(menu)) continue; - - this._avatarMenus.Add(menu); - IEnumerable subMenus = menu.controls - .Where(control => control.type == VRCExpressionsMenu.Control.ControlType.SubMenu) - .Select(control => control.subMenu); - - foreach (VRCExpressionsMenu subMenu in subMenus) { - queue.Enqueue(subMenu); - } - } - } - - private void FindMenuFolderCreators() { - if (this.targets.Length > 1) { - this._menuFolderCreators = null; - return; - } - - this._menuFolderCreators = new HashSet(); - VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform); - if (avatar == null) return; - foreach (ModularAvatarSubMenuCreator creator in avatar.gameObject - .GetComponentsInChildren() - .Where(creator => creator != this._creator)) { - this._menuFolderCreators.Add(creator); - } - } - - private bool IsMenuReachable(VRCAvatarDescriptor avatar, VRCExpressionsMenu menu) { - return this._avatarMenus == null || this._avatarMenus.Contains(menu); - } - - private bool IsMenuReachable(VRCAvatarDescriptor avatar, ModularAvatarSubMenuCreator creator, HashSet session) { - if (avatar == null) return true; - if (this._menuFolderCreators == null) return true; - - if (session.Contains(creator)) return false; - if (!this._menuFolderCreators.Contains(creator)) return false; - - if (!creator.enabled) return false; - session.Add(creator); - switch (creator.installTargetType) { - case InstallTargetType.VRCExpressionMenu: - return creator.installTargetMenu == null || this.IsMenuReachable(avatar, creator.installTargetMenu); - case InstallTargetType.FolderCreator: - return creator.installTargetCreator == null || this.IsMenuReachable(avatar, creator.installTargetCreator, session); - default: - throw new ArgumentOutOfRangeException(); - } - } - } -} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs.meta b/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs.meta deleted file mode 100644 index 6cdc3939..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/SubMenuCreatorEditor.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 87c99ae6e87240aa9b53fdbf8e962107 -timeCreated: 1669789624 \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs b/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs deleted file mode 100644 index f9f85732..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using VRC.SDK3.Avatars.Components; -using VRC.SDK3.Avatars.ScriptableObjects; -using static nadena.dev.modular_avatar.core.ModularAvatarSubMenuCreator; -using Object = UnityEngine.Object; - -namespace nadena.dev.modular_avatar.core.editor { - internal class SubMenuCreateHook { - private static readonly Texture2D _MORE_ICON = AssetDatabase.LoadAssetAtPath( - "Packages/nadena.dev.modular-avatar/Runtime/Icons/Icon_More_A.png" - ); - - private readonly Dictionary> _childMap; - private readonly List _rootCreators; - - private readonly Dictionary _clonedMenus; - private readonly Dictionary _creatFolders; - private Dictionary _installTargets; - - private VRCExpressionsMenu _rootMenu; - - public SubMenuCreateHook() { - this._childMap = new Dictionary>(); - this._rootCreators = new List(); - this._clonedMenus = new Dictionary(); - this._creatFolders = new Dictionary(); - } - - public void OnPreprocessAvatar(GameObject avatarRoot) { - this._childMap.Clear(); - this._rootCreators.Clear(); - this._clonedMenus.Clear(); - - this.MappingFolderCreator(avatarRoot); - VRCAvatarDescriptor avatar = avatarRoot.GetComponent(); - if (avatar.expressionsMenu == null) { - avatar.expressionsMenu = CreateMenuAsset(); - } - - this._rootMenu = avatar.expressionsMenu; - avatar.expressionsMenu = this.CloneMenu(avatar.expressionsMenu); - this._installTargets = new Dictionary(this._clonedMenus); - - foreach (ModularAvatarSubMenuCreator rootCreator in this._rootCreators.Where(rootCreator => rootCreator.enabled)) { - if (rootCreator.installTargetMenu == null) { - rootCreator.installTargetMenu = this._rootMenu; - } - - if (rootCreator.installTargetMenu == null) continue; - if (!this._installTargets.TryGetValue(rootCreator.installTargetMenu, out VRCExpressionsMenu targetMenu)) continue; - - if (!this._creatFolders.TryGetValue(rootCreator, out VRCExpressionsMenu folderMenu)) { - folderMenu = CreateMenuAsset(); - this._creatFolders[rootCreator] = folderMenu; - } - - AddSubMenuElement(targetMenu, rootCreator.folderName, folderMenu, rootCreator.icon); - if (!this._childMap.TryGetValue(rootCreator, out List children)) continue; - foreach (ModularAvatarSubMenuCreator child in children) { - this.CreateChildFolder(child); - } - this.SplitMenu(rootCreator); - - this.SplitParentMenu(targetMenu, rootCreator); - } - - ReassignmentMenuInstaller(avatarRoot); - } - - - private void CreateChildFolder(ModularAvatarSubMenuCreator creator) { - if (!this._creatFolders.TryGetValue(creator.installTargetCreator, out VRCExpressionsMenu targetMenu)) return; - if (!this._creatFolders.TryGetValue(creator, out VRCExpressionsMenu folderMenu)) { - // 子が1つの親を参照する関係なので、同じ要素が複数現れることはありえない。 - // 同様に循環参照等にもたどり付けないので考慮に入れなくてよい。 - folderMenu = CreateMenuAsset(); - this._creatFolders[creator] = folderMenu; - } - - AddSubMenuElement(targetMenu, creator.folderName, folderMenu, creator.icon); - if (!this._childMap.TryGetValue(creator, out List children)) return; - foreach (ModularAvatarSubMenuCreator child in children) { - this.CreateChildFolder(child); - } - - this.SplitMenu(creator); - } - - private void SplitMenu(ModularAvatarSubMenuCreator creator) { - VRCExpressionsMenu targetMenu = this._creatFolders[creator]; - while (targetMenu.controls.Count > VRCExpressionsMenu.MAX_CONTROLS) { - VRCExpressionsMenu newMenu = CreateMenuAsset(); - const int keepCount = VRCExpressionsMenu.MAX_CONTROLS - 1; - newMenu.controls.AddRange(targetMenu.controls.Skip(keepCount)); - targetMenu.controls.RemoveRange(keepCount, targetMenu.controls.Count - keepCount); - AddSubMenuElement(targetMenu, "More", newMenu, _MORE_ICON); - this._creatFolders[creator] = newMenu; - targetMenu = newMenu; - } - } - - private void SplitParentMenu(VRCExpressionsMenu targetMenu, ModularAvatarSubMenuCreator rootCreator) { - while (targetMenu.controls.Count > VRCExpressionsMenu.MAX_CONTROLS) { - VRCExpressionsMenu newMenu = CreateMenuAsset(); - const int keepCount = VRCExpressionsMenu.MAX_CONTROLS - 1; - newMenu.controls.AddRange(targetMenu.controls.Skip(keepCount)); - targetMenu.controls.RemoveRange(keepCount, targetMenu.controls.Count - keepCount); - AddSubMenuElement(targetMenu, "More", newMenu, _MORE_ICON); - this._installTargets[rootCreator.installTargetMenu] = newMenu; - targetMenu = newMenu; - } - } - - private void ReassignmentMenuInstaller(GameObject avatarRoot) { - ModularAvatarMenuInstaller[] menuInstallers = avatarRoot.GetComponentsInChildren(true) - .Where(installer => installer.enabled) - .ToArray(); - foreach (ModularAvatarMenuInstaller installer in menuInstallers) { - if (installer.installTargetMenu == null) { - installer.installTargetMenu = this._rootMenu; - } - - if (installer.InstallTargetType == InstallTargetType.VRCExpressionMenu || installer.installTargetCreator == null) { - installer.installTargetMenu = this._installTargets[installer.installTargetMenu]; - } else { - installer.installTargetMenu = this._creatFolders[installer.installTargetCreator]; - } - } - } - - private VRCExpressionsMenu CloneMenu(VRCExpressionsMenu menu) { - if (menu == null) return null; - if (this._clonedMenus.TryGetValue(menu, out VRCExpressionsMenu newMenu)) return newMenu; - newMenu = Object.Instantiate(menu); - AssetDatabase.CreateAsset(newMenu, Util.GenerateAssetPath()); - this._clonedMenus[menu] = newMenu; - - foreach (VRCExpressionsMenu.Control control in newMenu.controls.Where(control => control.type == VRCExpressionsMenu.Control.ControlType.SubMenu)) { - control.subMenu = this.CloneMenu(control.subMenu); - } - - return newMenu; - } - - private void MappingFolderCreator(GameObject avatarRoot) { - foreach (ModularAvatarSubMenuCreator creator in avatarRoot.GetComponentsInChildren(true)) { - if (!creator.enabled) continue; - if (creator.installTargetType == InstallTargetType.VRCExpressionMenu) { - this._rootCreators.Add(creator); - } else { - if (creator.installTargetCreator == null) { - this._rootCreators.Add(creator); - } else { - if (!this._childMap.TryGetValue(creator.installTargetCreator, out List children)) { - children = new List(); - this._childMap[creator.installTargetCreator] = children; - } - - children.Add(creator); - } - } - } - } - - private static void AddSubMenuElement(VRCExpressionsMenu targetMenu, string elementName, VRCExpressionsMenu subMenu, Texture2D icon = null) { - targetMenu.controls.Add(new VRCExpressionsMenu.Control() { - name = elementName, - type = VRCExpressionsMenu.Control.ControlType.SubMenu, - subMenu = subMenu, - parameter = new VRCExpressionsMenu.Control.Parameter { - name = "" - }, - subParameters = Array.Empty(), - icon = icon, - labels = Array.Empty() - }); - } - - private static VRCExpressionsMenu CreateMenuAsset() { - VRCExpressionsMenu menuFolder = ScriptableObject.CreateInstance(); - AssetDatabase.CreateAsset(menuFolder, Util.GenerateAssetPath()); - return menuFolder; - } - } -} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs.meta b/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs.meta deleted file mode 100644 index 30cd8c67..00000000 --- a/Packages/nadena.dev.modular-avatar/Editor/SubMenuCreateHook.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b732d550fcb1441a91b791c6caecac36 -timeCreated: 1669796064 \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuInstaller.cs b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuInstaller.cs index e02c5b15..db174b07 100644 --- a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuInstaller.cs +++ b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuInstaller.cs @@ -1,23 +1,20 @@ using UnityEngine; -using UnityEngine.Serialization; using VRC.SDK3.Avatars.Components; using VRC.SDK3.Avatars.ScriptableObjects; -using static nadena.dev.modular_avatar.core.ModularAvatarSubMenuCreator; namespace nadena.dev.modular_avatar.core { - [AddComponentMenu("Modular Avatar/MA Menu Installer")] - public class ModularAvatarMenuInstaller : AvatarTagComponent { - public InstallTargetType InstallTargetType; - public VRCExpressionsMenu menuToAppend; - public VRCExpressionsMenu installTargetMenu; - [FormerlySerializedAs("installTargetFolderCreator")] public ModularAvatarSubMenuCreator installTargetCreator; + [AddComponentMenu("Modular Avatar/MA Menu Installer")] + public class ModularAvatarMenuInstaller : AvatarTagComponent + { + public VRCExpressionsMenu menuToAppend; + public VRCExpressionsMenu installTargetMenu; - // ReSharper disable once Unity.RedundantEventFunction - void Start() - { - // Ensure that unity generates an enable checkbox - } - } + // ReSharper disable once Unity.RedundantEventFunction + void Start() + { + // Ensure that unity generates an enable checkbox + } + } } \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs deleted file mode 100644 index eda3330d..00000000 --- a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; -using VRC.SDK3.Avatars.ScriptableObjects; - -namespace nadena.dev.modular_avatar.core { - [AddComponentMenu("Modular Avatar/MA SubMenu Creator")] - public class ModularAvatarSubMenuCreator : AvatarTagComponent { - public InstallTargetType installTargetType; - public VRCExpressionsMenu installTargetMenu; - public ModularAvatarSubMenuCreator installTargetCreator; - public string folderName; - public Texture2D icon; - - - public enum InstallTargetType { - VRCExpressionMenu, - FolderCreator, - } - - } -} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs.meta b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs.meta deleted file mode 100644 index 329b40f8..00000000 --- a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarSubMenuCreator.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: af43171cf0e846c19c34c0420dac976a -timeCreated: 1669789344 \ No newline at end of file