mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
change: MA Info is now a normal editor window (#850)
This commit is contained in:
parent
61a70feed7
commit
bc12e3a985
@ -22,25 +22,29 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#region
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using nadena.dev.modular_avatar.ui;
|
using nadena.dev.modular_avatar.ui;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("Tests")]
|
[assembly: InternalsVisibleTo("Tests")]
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
{
|
{
|
||||||
public class AvatarProcessor
|
public class AvatarProcessor
|
||||||
{
|
{
|
||||||
[MenuItem("GameObject/ModularAvatar/Manual bake avatar", true, 100)]
|
[MenuItem(UnityMenuItems.GameObject_ManualBake, true, UnityMenuItems.GameObject_ManualBakeOrder)]
|
||||||
static bool ValidateApplyToCurrentAvatarGameobject()
|
static bool ValidateApplyToCurrentAvatarGameobject()
|
||||||
{
|
{
|
||||||
return ValidateApplyToCurrentAvatar();
|
return ValidateApplyToCurrentAvatar();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/ModularAvatar/Manual bake avatar", false, 100)]
|
[MenuItem(UnityMenuItems.GameObject_ManualBake, false, UnityMenuItems.GameObject_ManualBakeOrder)]
|
||||||
static void ApplyToCurrentAvatarGameobject()
|
static void ApplyToCurrentAvatarGameobject()
|
||||||
{
|
{
|
||||||
ApplyToCurrentAvatar();
|
ApplyToCurrentAvatar();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
@ -114,11 +115,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
internal static class EasySetupOutfit
|
internal static class EasySetupOutfit
|
||||||
{
|
{
|
||||||
private const int PRIORITY = 49;
|
|
||||||
private static string[] errorMessageGroups;
|
private static string[] errorMessageGroups;
|
||||||
private static string errorHeader;
|
private static string errorHeader;
|
||||||
|
|
||||||
[MenuItem("GameObject/ModularAvatar/Setup Outfit", false, PRIORITY)]
|
[MenuItem(UnityMenuItems.GameObject_SetupOutfit, false, UnityMenuItems.GameObject_SetupOutfitOrder)]
|
||||||
internal static void SetupOutfit(MenuCommand cmd)
|
internal static void SetupOutfit(MenuCommand cmd)
|
||||||
{
|
{
|
||||||
if (!ValidateSetupOutfit())
|
if (!ValidateSetupOutfit())
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
#region
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Reflection.Emit;
|
|
||||||
using HarmonyLib;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor.HarmonyPatches
|
|
||||||
{
|
|
||||||
internal static class InjectParamsUsageUI
|
|
||||||
{
|
|
||||||
private static readonly Type type = AccessTools.TypeByName("UnityEditor.PropertyEditor");
|
|
||||||
private static readonly PropertyInfo _editorsElement = AccessTools.Property(type, "editorsElement");
|
|
||||||
|
|
||||||
private static readonly Type editorElem = AccessTools.TypeByName("UnityEditor.UIElements.EditorElement");
|
|
||||||
private static readonly PropertyInfo editorElem_editor = AccessTools.Property(editorElem, "editor");
|
|
||||||
|
|
||||||
public static void Patch(Harmony h)
|
|
||||||
{
|
|
||||||
var type = AccessTools.TypeByName("UnityEditor.PropertyEditor");
|
|
||||||
var drawEditors = AccessTools.Method(type, "DrawEditors");
|
|
||||||
|
|
||||||
h.Patch(drawEditors, transpiler: new HarmonyMethod(typeof(InjectParamsUsageUI), nameof(Transpile)));
|
|
||||||
|
|
||||||
var objNames = AccessTools.TypeByName("UnityEditor.ObjectNames");
|
|
||||||
var m_GetObjectTypeName = AccessTools.Method(objNames, "GetObjectTypeName");
|
|
||||||
var postfix_GetObjectTypeName =
|
|
||||||
AccessTools.Method(typeof(InjectParamsUsageUI), nameof(Postfix_GetObjectTypeName));
|
|
||||||
|
|
||||||
h.Patch(m_GetObjectTypeName, postfix: new HarmonyMethod(postfix_GetObjectTypeName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Postfix_GetObjectTypeName(ref string __result, Object o)
|
|
||||||
{
|
|
||||||
if (o is ModularAvatarInformation)
|
|
||||||
{
|
|
||||||
__result = "Modular Avatar Information";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> ci)
|
|
||||||
{
|
|
||||||
var target = AccessTools.Method(typeof(VisualElement), "Add");
|
|
||||||
|
|
||||||
foreach (var i in ci)
|
|
||||||
{
|
|
||||||
if (i.opcode != OpCodes.Callvirt)
|
|
||||||
{
|
|
||||||
yield return i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i.opcode == OpCodes.Callvirt
|
|
||||||
&& i.operand is MethodInfo method
|
|
||||||
&& method == target
|
|
||||||
)
|
|
||||||
{
|
|
||||||
yield return new CodeInstruction(OpCodes.Ldarg_0);
|
|
||||||
yield return new CodeInstruction(OpCodes.Call,
|
|
||||||
AccessTools.Method(typeof(InjectParamsUsageUI), nameof(EditorAdd)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EditorAdd(VisualElement container, VisualElement child, object caller)
|
|
||||||
{
|
|
||||||
container.Add(child);
|
|
||||||
|
|
||||||
var editorsElement = _editorsElement.GetValue(caller) as VisualElement;
|
|
||||||
if (editorsElement != container)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!child.ClassListContains("game-object-inspector"))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var editor = editorElem_editor.GetValue(child) as Editor;
|
|
||||||
if (editor == null) return;
|
|
||||||
|
|
||||||
if (editor.targets.Length != 1) return;
|
|
||||||
|
|
||||||
if (editor.target is GameObject obj)
|
|
||||||
{
|
|
||||||
var elem = new ParamsUsageUI();
|
|
||||||
container.Add(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5d62a8f41641443ea8bffdc0429e0ad1
|
|
||||||
timeCreated: 1710223876
|
|
@ -17,7 +17,6 @@ namespace nadena.dev.modular_avatar.core.editor.HarmonyPatches
|
|||||||
#if UNITY_2022_3_OR_NEWER
|
#if UNITY_2022_3_OR_NEWER
|
||||||
HandleUtilityPatches.Patch_FilterInstanceIDs,
|
HandleUtilityPatches.Patch_FilterInstanceIDs,
|
||||||
PickingObjectPatch.Patch,
|
PickingObjectPatch.Patch,
|
||||||
InjectParamsUsageUI.Patch,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
#region
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.UIElements;
|
using UnityEditor.UIElements;
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.TestTools;
|
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
{
|
{
|
||||||
public class LogoElement : VisualElement
|
public class LogoElement : VisualElement
|
||||||
@ -85,19 +87,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
public LogoElement()
|
public LogoElement()
|
||||||
{
|
{
|
||||||
_inner = new VisualElement();
|
_inner = new LogoImage();
|
||||||
|
|
||||||
_inner.style.display = DisplayStyle.None;
|
_inner.style.display = DisplayStyle.None;
|
||||||
_inner.style.flexDirection = FlexDirection.Row;
|
|
||||||
_inner.style.alignItems = Align.Center;
|
|
||||||
_inner.style.justifyContent = Justify.Center;
|
|
||||||
|
|
||||||
var image = new Image();
|
|
||||||
image.image = LogoDisplay.LOGO_ASSET;
|
|
||||||
image.style.width = new Length(LogoDisplay.ImageWidth(LogoDisplay.TARGET_HEIGHT), LengthUnit.Pixel);
|
|
||||||
image.style.height = new Length(LogoDisplay.TARGET_HEIGHT, LengthUnit.Pixel);
|
|
||||||
|
|
||||||
_inner.Add(image);
|
|
||||||
this.Add(_inner);
|
this.Add(_inner);
|
||||||
|
|
||||||
RegisterCallback<GeometryChangedEvent>(OnGeomChanged);
|
RegisterCallback<GeometryChangedEvent>(OnGeomChanged);
|
||||||
|
38
Editor/Inspector/Common/LogoImage.cs
Normal file
38
Editor/Inspector/Common/LogoImage.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#region
|
||||||
|
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
|
{
|
||||||
|
public class LogoImage : VisualElement
|
||||||
|
{
|
||||||
|
VisualElement _inner;
|
||||||
|
|
||||||
|
public new class UxmlFactory : UxmlFactory<LogoImage, UxmlTraits>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public new class UxmlTraits : VisualElement.UxmlTraits
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogoImage()
|
||||||
|
{
|
||||||
|
_inner = new VisualElement();
|
||||||
|
|
||||||
|
_inner.style.flexDirection = FlexDirection.Row;
|
||||||
|
_inner.style.alignItems = Align.Center;
|
||||||
|
_inner.style.justifyContent = Justify.Center;
|
||||||
|
|
||||||
|
var image = new Image();
|
||||||
|
image.image = LogoDisplay.LOGO_ASSET;
|
||||||
|
image.style.width = new Length(LogoDisplay.ImageWidth(LogoDisplay.TARGET_HEIGHT), LengthUnit.Pixel);
|
||||||
|
image.style.height = new Length(LogoDisplay.TARGET_HEIGHT, LengthUnit.Pixel);
|
||||||
|
|
||||||
|
_inner.Add(image);
|
||||||
|
Add(_inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Editor/Inspector/Common/LogoImage.cs.meta
Normal file
3
Editor/Inspector/Common/LogoImage.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d12c8166c3f14b78a76dbef22b07fad1
|
||||||
|
timeCreated: 1715480586
|
@ -1,7 +1,11 @@
|
|||||||
using System;
|
#region
|
||||||
|
|
||||||
|
using System;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
{
|
{
|
||||||
internal static class LogoDisplay
|
internal static class LogoDisplay
|
||||||
@ -37,7 +41,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
internal static void DisplayLogo()
|
internal static void DisplayLogo()
|
||||||
{
|
{
|
||||||
if (LOGO_ASSET == null) return;
|
if (LOGO_ASSET == null || EditorStyles.label == null) return;
|
||||||
|
|
||||||
var height = TARGET_HEIGHT;
|
var height = TARGET_HEIGHT;
|
||||||
var width = ImageWidth(height);
|
var width = ImageWidth(height);
|
||||||
|
@ -246,5 +246,6 @@
|
|||||||
"ma_info.param_usage_ui.header": "Expressions Parameter Usage",
|
"ma_info.param_usage_ui.header": "Expressions Parameter Usage",
|
||||||
"ma_info.param_usage_ui.other_objects": "Other objects on this avatar",
|
"ma_info.param_usage_ui.other_objects": "Other objects on this avatar",
|
||||||
"ma_info.param_usage_ui.free_space": "Unused parameter space ({0} bits)",
|
"ma_info.param_usage_ui.free_space": "Unused parameter space ({0} bits)",
|
||||||
"ma_info.param_usage_ui.bits_template": "{0} ({1} bits)"
|
"ma_info.param_usage_ui.bits_template": "{0} ({1} bits)",
|
||||||
|
"ma_info.param_usage_ui.no_data": "[ NO DATA ]"
|
||||||
}
|
}
|
@ -242,5 +242,6 @@
|
|||||||
"ma_info.param_usage_ui.header": "Expressions Parameter 使用状況",
|
"ma_info.param_usage_ui.header": "Expressions Parameter 使用状況",
|
||||||
"ma_info.param_usage_ui.other_objects": "このアバター内の他のオブジェクト",
|
"ma_info.param_usage_ui.other_objects": "このアバター内の他のオブジェクト",
|
||||||
"ma_info.param_usage_ui.free_space": "未使用領域 ({0} 個のビット)",
|
"ma_info.param_usage_ui.free_space": "未使用領域 ({0} 個のビット)",
|
||||||
"ma_info.param_usage_ui.bits_template": "{0} ({1} 個のビットを使用中)"
|
"ma_info.param_usage_ui.bits_template": "{0} ({1} 個のビットを使用中)",
|
||||||
|
"ma_info.param_usage_ui.no_data": "[ NO DATA ]"
|
||||||
}
|
}
|
@ -1,19 +1,23 @@
|
|||||||
#if MA_VRCSDK3_AVATARS
|
#if MA_VRCSDK3_AVATARS
|
||||||
|
|
||||||
|
#region
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VRC.SDK3.Avatars.Components;
|
using VRC.SDK3.Avatars.Components;
|
||||||
using VRC.SDK3.Avatars.ScriptableObjects;
|
using VRC.SDK3.Avatars.ScriptableObjects;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
{
|
{
|
||||||
internal class MenuExtractor
|
internal class MenuExtractor
|
||||||
{
|
{
|
||||||
private const int PRIORITY = 49;
|
[MenuItem(UnityMenuItems.GameObject_ExtractMenu, false, UnityMenuItems.GameObject_ExtractMenuOrder)]
|
||||||
|
|
||||||
[MenuItem("GameObject/ModularAvatar/Extract menu", false, PRIORITY)]
|
|
||||||
static void ExtractMenu(MenuCommand menuCommand)
|
static void ExtractMenu(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
if (!(menuCommand.context is GameObject gameObj)) return;
|
if (!(menuCommand.context is GameObject gameObj)) return;
|
||||||
@ -32,10 +36,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
var assetPath = AssetDatabase.GetAssetPath(avatar.expressionsMenu);
|
var assetPath = AssetDatabase.GetAssetPath(avatar.expressionsMenu);
|
||||||
var dummyAssetPathBase = assetPath.Replace(".asset", " placeholder");
|
var dummyAssetPathBase = assetPath.Replace(".asset", " placeholder");
|
||||||
if (dummyAssetPathBase.StartsWith("Packages" + System.IO.Path.DirectorySeparatorChar))
|
if (dummyAssetPathBase.StartsWith("Packages" + Path.DirectorySeparatorChar))
|
||||||
{
|
{
|
||||||
var filename = System.IO.Path.GetFileName(dummyAssetPathBase);
|
var filename = Path.GetFileName(dummyAssetPathBase);
|
||||||
dummyAssetPathBase = System.IO.Path.Combine("Assets", filename);
|
dummyAssetPathBase = Path.Combine("Assets", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that a similarly-named file doesn't already exist
|
// Check that a similarly-named file doesn't already exist
|
||||||
@ -43,7 +47,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
var fullPath = dummyAssetPathBase + (i > 0 ? " " + i : "") + ".asset";
|
var fullPath = dummyAssetPathBase + (i > 0 ? " " + i : "") + ".asset";
|
||||||
if (System.IO.File.Exists(fullPath))
|
if (File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
var asset = AssetDatabase.LoadAssetAtPath<VRCExpressionsMenu>(fullPath);
|
var asset = AssetDatabase.LoadAssetAtPath<VRCExpressionsMenu>(fullPath);
|
||||||
if (asset != null && asset.controls.Count == 0)
|
if (asset != null && asset.controls.Count == 0)
|
||||||
@ -52,7 +56,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!System.IO.File.Exists(fullPath))
|
else if (!File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
var dummyAsset = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
|
var dummyAsset = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
|
||||||
AssetDatabase.CreateAsset(dummyAsset, fullPath);
|
AssetDatabase.CreateAsset(dummyAsset, fullPath);
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
#region
|
|
||||||
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
|
||||||
{
|
|
||||||
[HelpURL("https://m-a.nadena.dev/docs/intro?lang=auto")]
|
|
||||||
internal class ModularAvatarInformation : ScriptableObject
|
|
||||||
{
|
|
||||||
internal static ModularAvatarInformation _instance;
|
|
||||||
|
|
||||||
internal static ModularAvatarInformation instance
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_instance == null) _instance = CreateInstance<ModularAvatarInformation>();
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f902feee12ad4fcbb8a975bbea565ab1
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: a8edd5bd1a0a64a40aa99cc09fb5f198, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
#Outerbox {
|
#Outerbox {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
border-top-width: 1px;
|
border-top-width: 1px;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
border-left-width: 1px;
|
/*border-left-width: 1px;
|
||||||
border-right-width: 1px;
|
border-right-width: 1px;*/
|
||||||
border-color: black;
|
border-color: black;
|
||||||
|
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
@ -18,6 +20,11 @@
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Footer {
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
#UsageBox {
|
#UsageBox {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -73,3 +80,32 @@
|
|||||||
border-left-width: 4px;
|
border-left-width: 4px;
|
||||||
border-right-width: 4px;
|
border-right-width: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NO DATA display */
|
||||||
|
#Outerbox Toggle {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Why doesn't #Outerbox.no-data > .unity-foldout__content > * work here? */
|
||||||
|
#Outerbox.no-data #UsageBox {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Outerbox.no-data #Legend {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#NoData {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Outerbox.no-data #NoData {
|
||||||
|
font-size: 150%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
<UXML xmlns:ui="UnityEngine.UIElements" xmlns:ma="nadena.dev.modular_avatar.core.editor">
|
<UXML xmlns:ui="UnityEngine.UIElements" xmlns:ma="nadena.dev.modular_avatar.core.editor">
|
||||||
<ui:VisualElement name="root-box">
|
<ui:VisualElement name="root-box">
|
||||||
<ui:Label text="ma_info.param_usage_ui.header" class="header ndmf-tr"/>
|
<ma:LogoImage/>
|
||||||
|
|
||||||
|
<ui:Foldout text="ma_info.param_usage_ui.header" class="header ndmf-tr" name="Outerbox">
|
||||||
|
<ui:VisualElement name="NoData">
|
||||||
|
<ui:Label text="ma_info.param_usage_ui.no_data" class="ndmf-tr"/>
|
||||||
|
</ui:VisualElement>
|
||||||
|
|
||||||
<ui:VisualElement name="Outerbox">
|
|
||||||
<ui:VisualElement name="UsageBox">
|
<ui:VisualElement name="UsageBox">
|
||||||
<ui:VisualElement name="OtherObjects" style="background-color: #888888; flex-grow: 1;"/>
|
<ui:VisualElement name="OtherObjects" style="background-color: #888888; flex-grow: 1;"/>
|
||||||
<ui:VisualElement name="UnusedSpace" style="width: auto; background-color: #eeeeee; flex-grow: 1;"/>
|
<ui:VisualElement name="UnusedSpace" style="width: auto; background-color: #eeeeee; flex-grow: 1;"/>
|
||||||
@ -28,8 +32,10 @@
|
|||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
|
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
</ui:VisualElement>
|
</ui:Foldout>
|
||||||
|
|
||||||
|
<ui:VisualElement name="Footer">
|
||||||
<ma:LanguageSwitcherElement/>
|
<ma:LanguageSwitcherElement/>
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
|
</ui:VisualElement>
|
||||||
</UXML>
|
</UXML>
|
@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using nadena.dev.modular_avatar.ui;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
|
||||||
{
|
|
||||||
#if UNITY_2022_3_OR_NEWER
|
|
||||||
[FilePath("modular-avatar/ParamsUsagePrefs.asset", FilePathAttribute.Location.PreferencesFolder)]
|
|
||||||
internal sealed class ParamsUsagePrefs : ScriptableSingleton<ParamsUsagePrefs>
|
|
||||||
{
|
|
||||||
public static event Action<bool> OnChange_EnableInfoMenu;
|
|
||||||
|
|
||||||
[FormerlySerializedAs("EnableInfoMenu")] public bool enableInfoMenu = true;
|
|
||||||
|
|
||||||
[MenuItem(UnityMenuItems.TopMenu_EnableInfo, false, UnityMenuItems.TopMenu_EnableInfoOrder)]
|
|
||||||
private static void Menu_EnableInfo()
|
|
||||||
{
|
|
||||||
ParamsUsagePrefs.instance.enableInfoMenu = !ParamsUsagePrefs.instance.enableInfoMenu;
|
|
||||||
Menu.SetChecked(UnityMenuItems.TopMenu_EnableInfo, ParamsUsagePrefs.instance.enableInfoMenu);
|
|
||||||
ParamsUsagePrefs.instance.Save(true);
|
|
||||||
|
|
||||||
OnChange_EnableInfoMenu?.Invoke(ParamsUsagePrefs.instance.enableInfoMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
[InitializeOnLoadMethod]
|
|
||||||
private static void Initialize()
|
|
||||||
{
|
|
||||||
Menu.SetChecked(UnityMenuItems.TopMenu_EnableInfo, ParamsUsagePrefs.instance.enableInfoMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
internal sealed class ParamsUsagePrefs
|
|
||||||
{
|
|
||||||
public static ParamsUsagePrefs instance => new ParamsUsagePrefs();
|
|
||||||
public static event Action<bool> OnChange_EnableInfoMenu;
|
|
||||||
public bool enableInfoMenu => false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3ebf965fd4064a52896def62c36c6a90
|
|
||||||
timeCreated: 1713742583
|
|
@ -1,220 +0,0 @@
|
|||||||
#region
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using HarmonyLib;
|
|
||||||
using nadena.dev.ndmf.localization;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEditor.UIElements;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
|
||||||
{
|
|
||||||
internal class ParamsUsageUI : VisualElement
|
|
||||||
{
|
|
||||||
private static readonly Type editorElem = AccessTools.TypeByName("UnityEditor.UIElements.EditorElement");
|
|
||||||
private static readonly PropertyInfo editorElem_editor = AccessTools.Property(editorElem, "editor");
|
|
||||||
|
|
||||||
private class FoldoutState
|
|
||||||
{
|
|
||||||
public bool Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ConditionalWeakTable<VisualElement, FoldoutState> FoldoutStateHolder =
|
|
||||||
new ConditionalWeakTable<VisualElement, FoldoutState>();
|
|
||||||
|
|
||||||
private VisualElement _gameObjectEditorElement;
|
|
||||||
private Editor _parentEditor;
|
|
||||||
private Object _rawTarget;
|
|
||||||
private GameObject _target;
|
|
||||||
private ParamsUsageEditor _editor;
|
|
||||||
private FoldoutState _foldoutState;
|
|
||||||
|
|
||||||
private bool _recursing = false;
|
|
||||||
|
|
||||||
public ParamsUsageUI()
|
|
||||||
{
|
|
||||||
RegisterCallback<AttachToPanelEvent>(OnAttach);
|
|
||||||
RegisterCallback<DetachFromPanelEvent>(OnDetach);
|
|
||||||
|
|
||||||
LanguagePrefs.RegisterLanguageChangeCallback(this,
|
|
||||||
(self) => self.OnLanguageChangedCallback());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnChange_EnableState(bool enableState)
|
|
||||||
{
|
|
||||||
if (_editor != null)
|
|
||||||
{
|
|
||||||
Rebuild();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLanguageChangedCallback()
|
|
||||||
{
|
|
||||||
if (_editor != null)
|
|
||||||
{
|
|
||||||
Rebuild();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDetach(DetachFromPanelEvent evt)
|
|
||||||
{
|
|
||||||
if (_recursing) return;
|
|
||||||
|
|
||||||
Clear();
|
|
||||||
|
|
||||||
if (_editor != null)
|
|
||||||
{
|
|
||||||
Object.DestroyImmediate(_editor);
|
|
||||||
_editor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParamsUsagePrefs.OnChange_EnableInfoMenu -= OnChange_EnableState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAttach(AttachToPanelEvent evt)
|
|
||||||
{
|
|
||||||
if (_recursing) return;
|
|
||||||
|
|
||||||
Rebuild();
|
|
||||||
|
|
||||||
ParamsUsagePrefs.OnChange_EnableInfoMenu += OnChange_EnableState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Rebuild()
|
|
||||||
{
|
|
||||||
if (parent == null) return;
|
|
||||||
|
|
||||||
if (!ParamsUsagePrefs.instance.enableInfoMenu)
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetRedrawSensor();
|
|
||||||
|
|
||||||
if (_gameObjectEditorElement?.parent != parent)
|
|
||||||
{
|
|
||||||
_gameObjectEditorElement = null;
|
|
||||||
|
|
||||||
var kv = FindEditorElement();
|
|
||||||
if (kv != null)
|
|
||||||
{
|
|
||||||
var elem = kv.Value.Item1;
|
|
||||||
var index = kv.Value.Item2;
|
|
||||||
|
|
||||||
if (index != parent.Children().ToList().IndexOf(this))
|
|
||||||
{
|
|
||||||
_recursing = true;
|
|
||||||
var p = parent;
|
|
||||||
RemoveFromHierarchy();
|
|
||||||
p.Insert(index + 1, this);
|
|
||||||
_recursing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameObjectEditorElement = elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gameObjectEditorElement == null) return;
|
|
||||||
|
|
||||||
_parentEditor = editorElem_editor.GetValue(_gameObjectEditorElement) as Editor;
|
|
||||||
if (_parentEditor == null) return;
|
|
||||||
|
|
||||||
_rawTarget = _parentEditor.target;
|
|
||||||
_target = _rawTarget as GameObject;
|
|
||||||
|
|
||||||
if (_target == null) return;
|
|
||||||
|
|
||||||
Clear();
|
|
||||||
_redrawSensorActive = false;
|
|
||||||
BuildContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private (VisualElement, int)? FindEditorElement()
|
|
||||||
{
|
|
||||||
foreach (var (elem, index) in parent.Children().Select((e, i) => (e, i)))
|
|
||||||
{
|
|
||||||
if (elem.ClassListContains("game-object-inspector"))
|
|
||||||
{
|
|
||||||
return (elem, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _redrawSensorActive = false;
|
|
||||||
|
|
||||||
private void SetRedrawSensor()
|
|
||||||
{
|
|
||||||
if (_redrawSensorActive) return;
|
|
||||||
|
|
||||||
Clear();
|
|
||||||
_redrawSensorActive = true;
|
|
||||||
Add(new IMGUIContainer(() => EditorApplication.delayCall += Rebuild));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildContent()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
|
|
||||||
if (!FoldoutStateHolder.TryGetValue(parent, out _foldoutState))
|
|
||||||
{
|
|
||||||
_foldoutState = new FoldoutState();
|
|
||||||
FoldoutStateHolder.Add(parent, _foldoutState);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RuntimeUtil.FindAvatarTransformInParents(_target.transform) == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_editor = Editor.CreateEditorWithContext(new Object[] { ModularAvatarInformation.instance }, _target,
|
|
||||||
typeof(ParamsUsageEditor))
|
|
||||||
as ParamsUsageEditor;
|
|
||||||
|
|
||||||
if (_editor == null) return;
|
|
||||||
|
|
||||||
var inspectorElement = new InspectorElement(_editor);
|
|
||||||
|
|
||||||
Add(new IMGUIContainer(() =>
|
|
||||||
{
|
|
||||||
if (_gameObjectEditorElement?.parent != parent || _parentEditor == null ||
|
|
||||||
_parentEditor.target != _rawTarget)
|
|
||||||
{
|
|
||||||
EditorApplication.delayCall += Rebuild;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Event.current.rawType)
|
|
||||||
{
|
|
||||||
case EventType.Repaint:
|
|
||||||
case EventType.MouseMove:
|
|
||||||
case EventType.Layout:
|
|
||||||
break;
|
|
||||||
case EventType.MouseDrag:
|
|
||||||
case EventType.DragUpdated:
|
|
||||||
case EventType.DragPerform:
|
|
||||||
case EventType.DragExited:
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_foldoutState.Visible = EditorGUILayout.InspectorTitlebar(_foldoutState.Visible, _editor);
|
|
||||||
inspectorElement.style.display = _foldoutState.Visible ? DisplayStyle.Flex : DisplayStyle.None;
|
|
||||||
_editor.Visible = _foldoutState.Visible;
|
|
||||||
}));
|
|
||||||
_editor.Visible = _foldoutState.Visible;
|
|
||||||
Add(inspectorElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 18364f2754ed43c3baba0f1e18ac03cd
|
|
||||||
timeCreated: 1710226452
|
|
@ -1,7 +1,9 @@
|
|||||||
#region
|
#region
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using nadena.dev.ndmf;
|
using nadena.dev.ndmf;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -12,7 +14,7 @@ using VRC.SDK3.Avatars.ScriptableObjects;
|
|||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.editor
|
namespace nadena.dev.modular_avatar.core.editor
|
||||||
{
|
{
|
||||||
internal class ParamsUsageEditor : MAEditorBase
|
internal class ParamsUsageWindow : EditorWindow
|
||||||
{
|
{
|
||||||
[SerializeField] private StyleSheet uss;
|
[SerializeField] private StyleSheet uss;
|
||||||
[SerializeField] private VisualTreeAsset uxml;
|
[SerializeField] private VisualTreeAsset uxml;
|
||||||
@ -32,11 +34,59 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
if (_visible == value) return;
|
if (_visible == value) return;
|
||||||
_visible = value;
|
_visible = value;
|
||||||
|
|
||||||
if (_visible) Recalculate();
|
#if UNITY_2022_1_OR_NEWER
|
||||||
|
if (_visible)
|
||||||
|
{
|
||||||
|
Recalculate();
|
||||||
|
ObjectChangeEvents.changesPublished += OnChangesPublished;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectChangeEvents.changesPublished -= OnChangesPublished;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBecameVisible()
|
||||||
|
{
|
||||||
|
Visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBecameInvisible()
|
||||||
|
{
|
||||||
|
Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSelectionChange()
|
||||||
|
{
|
||||||
|
if (Visible)
|
||||||
|
{
|
||||||
|
Recalculate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_2022_1_OR_NEWER
|
#if UNITY_2022_1_OR_NEWER
|
||||||
|
[MenuItem(UnityMenuItems.TopMenu_EnableInfo, false, UnityMenuItems.TopMenu_EnableInfoOrder)]
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
var window = GetWindow<ParamsUsageWindow>();
|
||||||
|
window.titleContent = new GUIContent("MA Information");
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem(UnityMenuItems.GameObject_EnableInfo, false, UnityMenuItems.GameObject_EnableInfoOrder)]
|
||||||
|
public static void ShowWindowFromGameObject()
|
||||||
|
{
|
||||||
|
ShowWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem(UnityMenuItems.GameObject_EnableInfo, true, UnityMenuItems.GameObject_EnableInfoOrder)]
|
||||||
|
public static bool ValidateShowWindowFromGameObject()
|
||||||
|
{
|
||||||
|
return Selection.gameObjects.Length == 1;
|
||||||
|
}
|
||||||
|
|
||||||
private bool _delayPending = false;
|
private bool _delayPending = false;
|
||||||
|
|
||||||
private void DelayRecalculate()
|
private void DelayRecalculate()
|
||||||
@ -47,40 +97,46 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
private void OnChangesPublished(ref ObjectChangeEventStream stream)
|
private void OnChangesPublished(ref ObjectChangeEventStream stream)
|
||||||
{
|
{
|
||||||
|
if (_root == null || !_visible) return;
|
||||||
if (!_delayPending) EditorApplication.delayCall += DelayRecalculate;
|
if (!_delayPending) EditorApplication.delayCall += DelayRecalculate;
|
||||||
_delayPending = true;
|
_delayPending = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected override VisualElement CreateInnerInspectorGUI()
|
bool GUIIsReady()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return uxml != null && EditorStyles.label != null;
|
||||||
|
}
|
||||||
|
catch (NullReferenceException _)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void CreateGUI()
|
||||||
|
{
|
||||||
|
if (!GUIIsReady())
|
||||||
|
{
|
||||||
|
// After domain reload, the uxml field (and EditorStyles, etc) isn't initialized immediately.
|
||||||
|
// Try again in the next frame.
|
||||||
|
EditorApplication.delayCall += CreateGUI;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_root = uxml.CloneTree();
|
_root = uxml.CloneTree();
|
||||||
|
|
||||||
|
rootVisualElement.Add(_root);
|
||||||
_root.styleSheets.Add(uss);
|
_root.styleSheets.Add(uss);
|
||||||
Localization.L.LocalizeUIElements(_root);
|
Localization.L.LocalizeUIElements(_root);
|
||||||
|
|
||||||
_legendContainer = _root.Q<VisualElement>("Legend");
|
_legendContainer = _root.Q<VisualElement>("Legend");
|
||||||
_usageBoxContainer = _root.Q<VisualElement>("UsageBox");
|
_usageBoxContainer = _root.Q<VisualElement>("UsageBox");
|
||||||
|
|
||||||
#if UNITY_2022_1_OR_NEWER
|
|
||||||
_root.RegisterCallback<AttachToPanelEvent>(_evt =>
|
|
||||||
{
|
|
||||||
ObjectChangeEvents.changesPublished += OnChangesPublished;
|
|
||||||
Recalculate();
|
Recalculate();
|
||||||
});
|
|
||||||
|
|
||||||
_root.RegisterCallback<DetachFromPanelEvent>(_evt =>
|
|
||||||
{
|
|
||||||
ObjectChangeEvents.changesPublished -= OnChangesPublished;
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return _root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInnerInspectorGUI()
|
|
||||||
{
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<Color> Colors()
|
private static IEnumerable<Color> Colors()
|
||||||
{
|
{
|
||||||
@ -109,14 +165,24 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
{
|
{
|
||||||
if (_root == null || !_visible) return;
|
if (_root == null || !_visible) return;
|
||||||
|
|
||||||
var ctx = serializedObject.context as GameObject;
|
var objects = Selection.gameObjects;
|
||||||
|
var target = objects.Length == 1 ? objects[0] : null;
|
||||||
|
var avatarRoot = target != null
|
||||||
|
? RuntimeUtil.FindAvatarTransformInParents(target.transform)?.gameObject
|
||||||
|
: null;
|
||||||
|
|
||||||
if (ctx == null) return;
|
var outerbox = _root.Q<VisualElement>("Outerbox");
|
||||||
|
if (avatarRoot == null)
|
||||||
|
{
|
||||||
|
outerbox.AddToClassList("no-data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outerbox.RemoveFromClassList("no-data");
|
||||||
|
}
|
||||||
|
|
||||||
var avatarRoot = RuntimeUtil.FindAvatarTransformInParents(ctx.transform)?.gameObject;
|
var orderedPlugins = ParameterInfo.ForUI.GetParametersForObject(target)
|
||||||
if (avatarRoot == null) return;
|
|
||||||
|
|
||||||
var orderedPlugins = ParameterInfo.ForUI.GetParametersForObject(ctx)
|
|
||||||
.GroupBy(p => p.Plugin)
|
.GroupBy(p => p.Plugin)
|
||||||
.Select(group => (group.Key, group.Sum(p => p.BitUsage)))
|
.Select(group => (group.Key, group.Sum(p => p.BitUsage)))
|
||||||
.Where((kv, index) => kv.Item2 > 0)
|
.Where((kv, index) => kv.Item2 > 0)
|
@ -1,13 +1,32 @@
|
|||||||
namespace nadena.dev.modular_avatar.ui
|
namespace nadena.dev.modular_avatar.ui
|
||||||
{
|
{
|
||||||
internal class UnityMenuItems
|
internal static class UnityMenuItems
|
||||||
{
|
{
|
||||||
|
internal const string GameObject_SetupOutfit = "GameObject/Modular Avatar/Setup Outfit";
|
||||||
|
internal const int GameObject_SetupOutfitOrder = -1000;
|
||||||
|
|
||||||
|
internal const string GameObject_ManualBake = "GameObject/Modular Avatar/Manual Bake Avatar";
|
||||||
|
internal const int GameObject_ManualBakeOrder = GameObject_SetupOutfitOrder + 1;
|
||||||
|
|
||||||
|
// <separator>
|
||||||
|
|
||||||
|
internal const string GameObject_EnableInfo = "GameObject/Modular Avatar/Show Modular Avatar Information";
|
||||||
|
internal const int GameObject_EnableInfoOrder = -799;
|
||||||
|
|
||||||
|
internal const string GameObject_ExtractMenu = "GameObject/Modular Avatar/Extract Menu";
|
||||||
|
internal const int GameObject_ExtractMenuOrder = GameObject_EnableInfoOrder + 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal const string TopMenu_EditModeBoneSync = "Tools/Modular Avatar/Sync Bones in Edit Mode";
|
internal const string TopMenu_EditModeBoneSync = "Tools/Modular Avatar/Sync Bones in Edit Mode";
|
||||||
internal const int TopMenu_EditModeBoneSyncOrder = 100;
|
internal const int TopMenu_EditModeBoneSyncOrder = 100;
|
||||||
|
|
||||||
internal const string TopMenu_EnableInfo = "Tools/Modular Avatar/Show Modular Avatar Information";
|
internal const string TopMenu_EnableInfo = "Tools/Modular Avatar/Show Modular Avatar Information";
|
||||||
internal const int TopMenu_EnableInfoOrder = 101;
|
internal const int TopMenu_EnableInfoOrder = 101;
|
||||||
|
|
||||||
|
// <separator>
|
||||||
|
|
||||||
internal const string TopMenu_ManualBakeAvatar = "Tools/Modular Avatar/Manual Bake Avatar";
|
internal const string TopMenu_ManualBakeAvatar = "Tools/Modular Avatar/Manual Bake Avatar";
|
||||||
internal const int TopMenu_ManualBakeAvatarOrder = 1000;
|
internal const int TopMenu_ManualBakeAvatarOrder = 1000;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user