mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-28 10:15:06 +08:00
chore: use ndmf Avatar Root api where applicable (#482)
* expose ndmf AvatarRoot APIs through ma.RuntimeUtil * refactor: prefer RuntimeUtil helpers for checking avatar root * refactor: ndmf.BuildContext represents Avatar (log) * refactor: ndmf.BuildContext represents Avatar (WorldFixed) * refactor: ndmf.BuildContext represents Avatar (FirstPersonVisible) * refactor: ndmf.BuildContext represents Avatar (BlendShapeSync) * refactor: prefer FindAvatarTransformInParents() (ErrorReportUI) * refactor: prefer FindAvatarTransformInParents() (Runtime) * refactor: prefer FindAvatarTransformInParents() (Editor) * delegate more ndmf AvatarRoot APIs through ma.RuntimeUtil
This commit is contained in:
parent
939e63c297
commit
ae7103cf82
@ -57,7 +57,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
_boneDatabase = boneDatabase;
|
||||
_pathMappings = context.PluginBuildContext.Extension<AnimationServicesContext>().PathMappings;
|
||||
|
||||
while (root != null && root.GetComponent<VRCAvatarDescriptor>() == null)
|
||||
while (root != null && !RuntimeUtil.IsAvatarRoot(root))
|
||||
{
|
||||
var originalPath = RuntimeUtil.AvatarRootPath(root.gameObject);
|
||||
System.Diagnostics.Debug.Assert(originalPath != null);
|
||||
|
@ -42,16 +42,17 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPreprocessAvatar(GameObject avatar, BuildContext context)
|
||||
public void OnPreprocessAvatar(BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
var avatarGameObject = context.AvatarRootObject;
|
||||
var animDb = _context.AnimationDatabase;
|
||||
|
||||
var avatarDescriptor = avatar.GetComponent<VRCAvatarDescriptor>();
|
||||
var avatarDescriptor = context.AvatarDescriptor;
|
||||
_bindingMappings = new Dictionary<SummaryBinding, List<SummaryBinding>>();
|
||||
_motionCache = new Dictionary<Motion, Motion>();
|
||||
|
||||
var components = avatarDescriptor.GetComponentsInChildren<ModularAvatarBlendshapeSync>(true);
|
||||
var components = avatarGameObject.GetComponentsInChildren<ModularAvatarBlendshapeSync>(true);
|
||||
if (components.Length == 0) return;
|
||||
|
||||
var layers = avatarDescriptor.baseAnimationLayers;
|
||||
@ -77,7 +78,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
foreach (var component in components)
|
||||
{
|
||||
BuildReport.ReportingObject(component, () => ProcessComponent(avatarDescriptor, component));
|
||||
BuildReport.ReportingObject(component, () => ProcessComponent(avatarGameObject, component));
|
||||
}
|
||||
|
||||
// Walk and transform all clips
|
||||
@ -91,9 +92,9 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
});
|
||||
}
|
||||
|
||||
private void ProcessComponent(VRCAvatarDescriptor avatarDescriptor, ModularAvatarBlendshapeSync component)
|
||||
private void ProcessComponent(GameObject avatarGameObject, ModularAvatarBlendshapeSync component)
|
||||
{
|
||||
var targetObj = RuntimeUtil.RelativePath(avatarDescriptor.gameObject, component.gameObject);
|
||||
var targetObj = RuntimeUtil.RelativePath(avatarGameObject, component.gameObject);
|
||||
|
||||
foreach (var binding in component.Bindings)
|
||||
{
|
||||
@ -102,7 +103,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var refSmr = refObj.GetComponent<SkinnedMeshRenderer>();
|
||||
if (refSmr == null) continue;
|
||||
|
||||
var refPath = RuntimeUtil.RelativePath(avatarDescriptor.gameObject, refObj);
|
||||
var refPath = RuntimeUtil.RelativePath(avatarGameObject, refObj);
|
||||
|
||||
var srcBinding = new SummaryBinding(refPath, binding.Blendshape);
|
||||
|
||||
|
@ -15,6 +15,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
internal readonly nadena.dev.ndmf.BuildContext PluginBuildContext;
|
||||
|
||||
internal VRCAvatarDescriptor AvatarDescriptor => PluginBuildContext.AvatarDescriptor;
|
||||
internal GameObject AvatarRootObject => PluginBuildContext.AvatarRootObject;
|
||||
internal Transform AvatarRootTransform => PluginBuildContext.AvatarRootTransform;
|
||||
|
||||
internal AnimationDatabase AnimationDatabase =>
|
||||
PluginBuildContext.Extension<AnimationServicesContext>().AnimationDatabase;
|
||||
@ -50,6 +52,11 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
}
|
||||
|
||||
public BuildContext(GameObject avatarGameObject)
|
||||
: this(new ndmf.BuildContext(avatarGameObject, null))
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveAsset(Object obj)
|
||||
{
|
||||
if (!SaveImmediate || AssetDatabase.IsMainAsset(obj) || AssetDatabase.IsSubAsset(obj)) return;
|
||||
|
@ -280,16 +280,16 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
// descriptors when transplanting outfits. Block this (and require that there be only one avdesc) by
|
||||
// refusing to run if we detect multiple avatar descriptors above the current object (or if we're run on
|
||||
// the avdesc object itself)
|
||||
var nearestAvatar = RuntimeUtil.FindAvatarInParents(xform);
|
||||
if (nearestAvatar == null || nearestAvatar.transform == xform)
|
||||
var nearestAvatarTransform = RuntimeUtil.FindAvatarTransformInParents(xform);
|
||||
if (nearestAvatarTransform == null || nearestAvatarTransform == xform)
|
||||
{
|
||||
errorMessageGroups = new string[]
|
||||
{S_f("setup_outfit.err.multiple_avatar_descriptors", xform.gameObject.name)};
|
||||
return false;
|
||||
}
|
||||
|
||||
var parent = nearestAvatar.transform.parent;
|
||||
if (parent != null && RuntimeUtil.FindAvatarInParents(parent) != null)
|
||||
var parent = nearestAvatarTransform.parent;
|
||||
if (parent != null && RuntimeUtil.FindAvatarTransformInParents(parent) != null)
|
||||
{
|
||||
errorMessageGroups = new string[]
|
||||
{
|
||||
@ -308,7 +308,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
avatarHips = outfitHips = null;
|
||||
var outfitRoot = obj as GameObject;
|
||||
avatarRoot = outfitRoot != null
|
||||
? RuntimeUtil.FindAvatarInParents(outfitRoot.transform)?.gameObject
|
||||
? RuntimeUtil.FindAvatarTransformInParents(outfitRoot.transform)?.gameObject
|
||||
: null;
|
||||
|
||||
if (avatarRoot == null)
|
||||
|
@ -5,7 +5,6 @@ using System.Linq;
|
||||
using nadena.dev.modular_avatar.core;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
@ -273,17 +272,17 @@ namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
}
|
||||
}
|
||||
|
||||
internal IDisposable ReportingOnAvatar(VRCAvatarDescriptor descriptor)
|
||||
internal IDisposable ReportingOnAvatar(GameObject avatarGameObject)
|
||||
{
|
||||
if (descriptor != null)
|
||||
if (avatarGameObject != null)
|
||||
{
|
||||
AvatarReport report = new AvatarReport();
|
||||
report.objectRef = new ObjectRef(descriptor.gameObject);
|
||||
report.objectRef = new ObjectRef(avatarGameObject);
|
||||
Avatars.Add(report);
|
||||
_currentAvatar = report;
|
||||
_currentAvatar.successful = true;
|
||||
|
||||
_currentAvatar.logs.AddRange(ComponentValidation.ValidateAll(descriptor.gameObject));
|
||||
_currentAvatar.logs.AddRange(ComponentValidation.ValidateAll(avatarGameObject));
|
||||
}
|
||||
|
||||
return new AvatarReportScope();
|
||||
|
@ -110,7 +110,7 @@ namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
GameObject activeAvatarObject = null;
|
||||
if (Selection.gameObjects.Length == 1)
|
||||
{
|
||||
activeAvatarObject = RuntimeUtil.FindAvatarInParents(Selection.activeGameObject.transform)?.gameObject;
|
||||
activeAvatarObject = RuntimeUtil.FindAvatarTransformInParents(Selection.activeGameObject.transform)?.gameObject;
|
||||
activeAvatar = BuildReport.CurrentReport.Avatars.FirstOrDefault(av =>
|
||||
av.objectRef.path == RuntimeUtil.RelativePath(null, activeAvatarObject)
|
||||
|| av.objectRef.path == RuntimeUtil.RelativePath(null, activeAvatarObject) + "(Clone)");
|
||||
|
@ -356,7 +356,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
internal static void RenameBonesByHeuristic(ModularAvatarMergeArmature config)
|
||||
{
|
||||
var target = config.mergeTarget.Get(RuntimeUtil.FindAvatarInParents(config.transform));
|
||||
var target = config.mergeTarget.Get(RuntimeUtil.FindAvatarTransformInParents(config.transform));
|
||||
if (target == null) return;
|
||||
|
||||
Traverse(config.transform, target.transform);
|
||||
|
@ -1,6 +1,5 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
@ -34,15 +33,15 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
try
|
||||
{
|
||||
var avatar = findContainingAvatar(property);
|
||||
if (avatar == null) return false;
|
||||
var avatarTransform = findContainingAvatarTransform(property);
|
||||
if (avatarTransform == null) return false;
|
||||
|
||||
bool isRoot = property.stringValue == AvatarObjectReference.AVATAR_ROOT;
|
||||
bool isNull = string.IsNullOrEmpty(property.stringValue);
|
||||
Transform target;
|
||||
if (isNull) target = null;
|
||||
else if (isRoot) target = avatar.transform;
|
||||
else target = avatar.transform.Find(property.stringValue);
|
||||
else if (isRoot) target = avatarTransform;
|
||||
else target = avatarTransform.Find(property.stringValue);
|
||||
|
||||
var labelRect = position;
|
||||
position = EditorGUI.PrefixLabel(position, label);
|
||||
@ -62,14 +61,14 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
property.stringValue = "";
|
||||
}
|
||||
else if (newTarget == avatar.transform)
|
||||
else if (newTarget == avatarTransform)
|
||||
{
|
||||
property.stringValue = AvatarObjectReference.AVATAR_ROOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
var relPath =
|
||||
RuntimeUtil.RelativePath(avatar.gameObject, ((Transform) newTarget).gameObject);
|
||||
RuntimeUtil.RelativePath(avatarTransform.gameObject, ((Transform) newTarget).gameObject);
|
||||
if (relPath == null) return true;
|
||||
|
||||
property.stringValue = relPath;
|
||||
@ -93,14 +92,14 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
property.stringValue = "";
|
||||
}
|
||||
else if (newTarget == avatar.transform)
|
||||
else if (newTarget == avatarTransform)
|
||||
{
|
||||
property.stringValue = AvatarObjectReference.AVATAR_ROOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
var relPath =
|
||||
RuntimeUtil.RelativePath(avatar.gameObject, ((Transform) newTarget).gameObject);
|
||||
RuntimeUtil.RelativePath(avatarTransform.gameObject, ((Transform) newTarget).gameObject);
|
||||
if (relPath == null) return true;
|
||||
|
||||
property.stringValue = relPath;
|
||||
@ -122,12 +121,12 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
private static VRCAvatarDescriptor findContainingAvatar(SerializedProperty property)
|
||||
private static Transform findContainingAvatarTransform(SerializedProperty property)
|
||||
{
|
||||
// Find containing object, and from that the avatar
|
||||
if (property.serializedObject == null) return null;
|
||||
|
||||
VRCAvatarDescriptor commonAvatar = null;
|
||||
Transform commonAvatar = null;
|
||||
var targets = property.serializedObject.targetObjects;
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
@ -135,7 +134,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
if (obj == null) return null;
|
||||
|
||||
var transform = obj.transform;
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(transform);
|
||||
var avatar = RuntimeUtil.FindAvatarTransformInParents(transform);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
|
@ -263,7 +263,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
if (_window != null) DestroyImmediate(_window);
|
||||
_window = ScriptableObject.CreateInstance<BlendshapeSelectWindow>();
|
||||
_window.AvatarRoot = RuntimeUtil.FindAvatarInParents(((ModularAvatarBlendshapeSync) target).transform)
|
||||
_window.AvatarRoot = RuntimeUtil.FindAvatarTransformInParents(((ModularAvatarBlendshapeSync) target).transform)
|
||||
.gameObject;
|
||||
_window.OfferBinding += OfferBinding;
|
||||
_window.Show();
|
||||
|
@ -50,10 +50,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
var t = (ModularAvatarBoneProxy) targets[i];
|
||||
var av = RuntimeUtil.FindAvatarInParents(t.transform);
|
||||
var avTr = RuntimeUtil.FindAvatarTransformInParents(t.transform);
|
||||
|
||||
if (av != null && parentAvatar == null) parentAvatar = av.gameObject;
|
||||
if (av == null || parentAvatar != av.gameObject)
|
||||
if (avTr != null && parentAvatar == null) parentAvatar = avTr.gameObject;
|
||||
if (avTr == null || parentAvatar != avTr.gameObject)
|
||||
{
|
||||
suppressTarget = true;
|
||||
break;
|
||||
@ -91,7 +91,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var t = (ModularAvatarBoneProxy) targets[i];
|
||||
Undo.RecordObjects(targets, "Set targets");
|
||||
var xform = ((TempObjRef) objRefs[i]).target;
|
||||
if (RuntimeUtil.FindAvatarInParents(xform)?.gameObject != parentAvatar) continue;
|
||||
if (RuntimeUtil.FindAvatarTransformInParents(xform)?.gameObject != parentAvatar) continue;
|
||||
t.target = xform;
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
private void OnEnable()
|
||||
{
|
||||
var target = (ModularAvatarVisibleHeadAccessory) this.target;
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(target.transform);
|
||||
var avatar = RuntimeUtil.FindAvatarTransformInParents(target.transform);
|
||||
|
||||
if (avatar != null) _processor = new VisibleHeadAccessoryProcessor(avatar);
|
||||
if (avatar != null) _processor = new VisibleHeadAccessoryProcessor(new BuildContext(avatar.gameObject));
|
||||
}
|
||||
|
||||
protected override void OnInnerInspectorGUI()
|
||||
|
@ -20,7 +20,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var target = targets[0] as Component;
|
||||
if (target == null) return;
|
||||
|
||||
if (RuntimeUtil.FindAvatarInParents(target.transform) == null)
|
||||
if (RuntimeUtil.FindAvatarTransformInParents(target.transform) == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(Localization.S("hint.not_in_avatar"), MessageType.Warning);
|
||||
}
|
||||
|
@ -41,11 +41,11 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
if (targets.Length == 1)
|
||||
{
|
||||
settings = (ModularAvatarMeshSettings) target;
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(settings.transform);
|
||||
if (avatar != null)
|
||||
var avatarTransform = RuntimeUtil.FindAvatarTransformInParents(settings.transform);
|
||||
if (avatarTransform != null)
|
||||
{
|
||||
Component mesh = (Component) target;
|
||||
merged = MeshSettingsPass.MergeSettings(avatar.transform, mesh.transform);
|
||||
merged = MeshSettingsPass.MergeSettings(avatarTransform, mesh.transform);
|
||||
haveMerged = true;
|
||||
}
|
||||
}
|
||||
|
@ -180,9 +180,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
[CanBeNull]
|
||||
public Mesh Retarget()
|
||||
{
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(renderer.transform);
|
||||
if (avatar == null) throw new System.Exception("Could not find avatar in parents of " + renderer.name);
|
||||
var avatarTransform = avatar.transform;
|
||||
var avatarTransform = RuntimeUtil.FindAvatarTransformInParents(renderer.transform);
|
||||
if (avatarTransform == null) throw new System.Exception("Could not find avatar in parents of " + renderer.name);
|
||||
|
||||
var avPos = avatarTransform.position;
|
||||
var avRot = avatarTransform.rotation;
|
||||
|
@ -16,7 +16,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
BuildContext = new BuildContext(context);
|
||||
}
|
||||
|
||||
toDispose = BuildReport.CurrentReport.ReportingOnAvatar(context.AvatarDescriptor);
|
||||
toDispose = BuildReport.CurrentReport.ReportingOnAvatar(context.AvatarRootObject);
|
||||
}
|
||||
|
||||
public void OnDeactivate(ndmf.BuildContext context)
|
||||
|
@ -42,7 +42,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin
|
||||
seq.Run(BoneProxyPluginPass.Instance);
|
||||
seq.Run(VisibleHeadAccessoryPluginPass.Instance);
|
||||
seq.Run("World Fixed Object",
|
||||
ctx => new WorldFixedObjectProcessor(ctx.AvatarDescriptor).Process(ctx)
|
||||
ctx => new WorldFixedObjectProcessor().Process(ctx)
|
||||
);
|
||||
seq.Run(ReplaceObjectPluginPass.Instance);
|
||||
seq.Run(BlendshapeSyncAnimationPluginPass.Instance);
|
||||
@ -186,7 +186,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin
|
||||
{
|
||||
protected override void Execute(ndmf.BuildContext context)
|
||||
{
|
||||
new VisibleHeadAccessoryProcessor(context.AvatarDescriptor).Process(MAContext(context));
|
||||
new VisibleHeadAccessoryProcessor(MAContext(context)).Process();
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin
|
||||
{
|
||||
protected override void Execute(ndmf.BuildContext context)
|
||||
{
|
||||
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(context.AvatarRootObject, MAContext(context));
|
||||
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(MAContext(context));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ using JetBrains.Annotations;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using VRC.SDKBase.Editor.BuildPipeline;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
@ -238,7 +237,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
var component = ptr.GetComponent<T>();
|
||||
if (component != null) yield return component;
|
||||
if (ptr.GetComponent<VRCAvatarDescriptor>() != null) break;
|
||||
if (RuntimeUtil.IsAvatarRoot(ptr)) break;
|
||||
ptr = ptr.parent;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using VRC.SDK3.Dynamics.PhysBone.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
@ -19,21 +18,23 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
InPhysBoneChain
|
||||
}
|
||||
|
||||
private VRCAvatarDescriptor _avatar;
|
||||
private BuildContext _context;
|
||||
private Transform _avatarTransform;
|
||||
private HashSet<Transform> _activeBones = new HashSet<Transform>();
|
||||
private Transform _headBone;
|
||||
|
||||
private HashSet<Transform> _visibleBones = new HashSet<Transform>();
|
||||
private Transform _proxyHead;
|
||||
|
||||
public VisibleHeadAccessoryProcessor(VRCAvatarDescriptor avatar)
|
||||
public VisibleHeadAccessoryProcessor(BuildContext context)
|
||||
{
|
||||
_avatar = avatar;
|
||||
_context = context;
|
||||
_avatarTransform = context.AvatarRootTransform;
|
||||
|
||||
var animator = avatar.GetComponent<Animator>();
|
||||
var animator = _avatarTransform.GetComponent<Animator>();
|
||||
_headBone = animator != null ? animator.GetBoneTransform(HumanBodyBones.Head) : null;
|
||||
|
||||
foreach (var physBone in avatar.GetComponentsInChildren<VRCPhysBone>(true))
|
||||
foreach (var physBone in _avatarTransform.GetComponentsInChildren<VRCPhysBone>(true))
|
||||
{
|
||||
var boneRoot = physBone.rootTransform != null ? physBone.rootTransform : physBone.transform;
|
||||
var ignored = new HashSet<Transform>(physBone.ignoreTransforms);
|
||||
@ -56,11 +57,11 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
public void Process(BuildContext context)
|
||||
public void Process()
|
||||
{
|
||||
bool didWork = false;
|
||||
|
||||
foreach (var target in _avatar.GetComponentsInChildren<ModularAvatarVisibleHeadAccessory>(true))
|
||||
foreach (var target in _avatarTransform.GetComponentsInChildren<ModularAvatarVisibleHeadAccessory>(true))
|
||||
{
|
||||
var w = BuildReport.ReportingObject(target, () => Process(target));
|
||||
didWork = didWork || w;
|
||||
@ -69,10 +70,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
if (didWork)
|
||||
{
|
||||
// Process meshes
|
||||
foreach (var smr in _avatar.GetComponentsInChildren<SkinnedMeshRenderer>(true))
|
||||
foreach (var smr in _avatarTransform.GetComponentsInChildren<SkinnedMeshRenderer>(true))
|
||||
{
|
||||
BuildReport.ReportingObject(smr,
|
||||
() => new VisibleHeadAccessoryMeshProcessor(smr, _visibleBones, _proxyHead).Retarget(context));
|
||||
() => new VisibleHeadAccessoryMeshProcessor(smr, _visibleBones, _proxyHead).Retarget(_context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,25 +3,20 @@ using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
internal class WorldFixedObjectProcessor
|
||||
{
|
||||
private BuildContext _context;
|
||||
private VRCAvatarDescriptor _avatar;
|
||||
private Transform _avatarTransform;
|
||||
private Transform _proxy;
|
||||
|
||||
public WorldFixedObjectProcessor(VRCAvatarDescriptor avatar)
|
||||
{
|
||||
_avatar = avatar;
|
||||
}
|
||||
|
||||
public void Process(BuildContext context)
|
||||
{
|
||||
_avatarTransform = context.AvatarRootTransform;
|
||||
_context = context;
|
||||
foreach (var target in _avatar.GetComponentsInChildren<ModularAvatarWorldFixedObject>(true)
|
||||
foreach (var target in _avatarTransform.GetComponentsInChildren<ModularAvatarWorldFixedObject>(true)
|
||||
.OrderByDescending(x => NestCount(x.transform)))
|
||||
BuildReport.ReportingObject(target, () => Process(target));
|
||||
}
|
||||
@ -66,7 +61,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var fixedGameObject = AssetDatabase.LoadAssetAtPath<GameObject>(
|
||||
AssetDatabase.GUIDToAssetPath("78828bfbcb4cb4ce3b00de044eb2d927"));
|
||||
|
||||
var avatarRoot = _avatar.transform;
|
||||
var avatarRoot = _avatarTransform;
|
||||
GameObject obj = new GameObject("(MA WorldFixedRoot)");
|
||||
|
||||
obj.transform.SetParent(avatarRoot, false);
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core
|
||||
{
|
||||
@ -34,16 +33,16 @@ namespace nadena.dev.modular_avatar.core
|
||||
RuntimeUtil.OnHierarchyChanged -= InvalidateCache;
|
||||
RuntimeUtil.OnHierarchyChanged += InvalidateCache;
|
||||
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(container.transform);
|
||||
if (avatar == null) return (_cachedReference = null);
|
||||
var avatarTransform = RuntimeUtil.FindAvatarTransformInParents(container.transform);
|
||||
if (avatarTransform == null) return (_cachedReference = null);
|
||||
|
||||
if (referencePath == AVATAR_ROOT)
|
||||
{
|
||||
_cachedReference = avatar.gameObject;
|
||||
_cachedReference = avatarTransform.gameObject;
|
||||
return _cachedReference;
|
||||
}
|
||||
|
||||
_cachedReference = avatar.transform.Find(referencePath)?.gameObject;
|
||||
_cachedReference = avatarTransform.Find(referencePath)?.gameObject;
|
||||
if (_cachedReference == null) return null;
|
||||
|
||||
// https://github.com/bdunderscore/modular-avatar/issues/308
|
||||
@ -72,7 +71,7 @@ namespace nadena.dev.modular_avatar.core
|
||||
{
|
||||
referencePath = "";
|
||||
}
|
||||
else if (target.GetComponent<VRCAvatarDescriptor>() != null)
|
||||
else if (RuntimeUtil.IsAvatarRoot(target.transform))
|
||||
{
|
||||
referencePath = AVATAR_ROOT;
|
||||
}
|
||||
|
@ -161,20 +161,20 @@ namespace nadena.dev.modular_avatar.core
|
||||
return null;
|
||||
}
|
||||
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(transform);
|
||||
if (avatar == null) return null;
|
||||
var avatarTransform = RuntimeUtil.FindAvatarTransformInParents(transform);
|
||||
if (avatarTransform == null) return null;
|
||||
|
||||
if (subPath == "$$AVATAR")
|
||||
{
|
||||
return avatar.transform;
|
||||
return avatarTransform;
|
||||
}
|
||||
|
||||
if (boneReference == HumanBodyBones.LastBone)
|
||||
{
|
||||
return avatar.transform.Find(subPath);
|
||||
return avatarTransform.Find(subPath);
|
||||
}
|
||||
|
||||
var animator = avatar.GetComponent<Animator>();
|
||||
var animator = avatarTransform.GetComponent<Animator>();
|
||||
if (animator == null) return null;
|
||||
var bone = animator.GetBoneTransform(boneReference);
|
||||
if (bone == null) return null;
|
||||
@ -184,9 +184,9 @@ namespace nadena.dev.modular_avatar.core
|
||||
|
||||
private void UpdateStaticMapping(Transform newTarget)
|
||||
{
|
||||
var avatar = RuntimeUtil.FindAvatarInParents(transform);
|
||||
var avatarTransform = RuntimeUtil.FindAvatarTransformInParents(transform);
|
||||
var humanBones = new Dictionary<Transform, HumanBodyBones>();
|
||||
var animator = avatar.GetComponent<Animator>();
|
||||
var animator = avatarTransform.GetComponent<Animator>();
|
||||
if (animator == null)
|
||||
{
|
||||
return;
|
||||
@ -201,7 +201,6 @@ namespace nadena.dev.modular_avatar.core
|
||||
}
|
||||
|
||||
Transform iter = newTarget;
|
||||
Transform avatarTransform = avatar.transform;
|
||||
|
||||
if (newTarget == avatarTransform)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ namespace nadena.dev.modular_avatar.core
|
||||
public void InferPrefixSuffix()
|
||||
{
|
||||
// We only infer if targeting the armature (below the Hips bone)
|
||||
var rootAnimator = RuntimeUtil.FindAvatarInParents(transform)?.GetComponent<Animator>();
|
||||
var rootAnimator = RuntimeUtil.FindAvatarTransformInParents(transform)?.GetComponent<Animator>();
|
||||
if (rootAnimator == null) return;
|
||||
|
||||
var hips = rootAnimator.GetBoneTransform(HumanBodyBones.Hips);
|
||||
|
@ -63,28 +63,18 @@ namespace nadena.dev.modular_avatar.core
|
||||
[CanBeNull]
|
||||
public static string RelativePath(GameObject root, GameObject child)
|
||||
{
|
||||
if (root == child) return "";
|
||||
|
||||
List<string> pathSegments = new List<string>();
|
||||
while (child != root && child != null)
|
||||
{
|
||||
pathSegments.Add(child.name);
|
||||
child = child.transform.parent?.gameObject;
|
||||
}
|
||||
|
||||
if (child == null && root != null) return null;
|
||||
|
||||
pathSegments.Reverse();
|
||||
return String.Join("/", pathSegments);
|
||||
return ndmf.runtime.RuntimeUtil.RelativePath(root, child);
|
||||
}
|
||||
|
||||
[CanBeNull]
|
||||
public static string AvatarRootPath(GameObject child)
|
||||
{
|
||||
if (child == null) return null;
|
||||
var avatar = FindAvatarInParents(child.transform);
|
||||
if (avatar == null) return null;
|
||||
return RelativePath(avatar.gameObject, child);
|
||||
return ndmf.runtime.RuntimeUtil.AvatarRootPath(child);
|
||||
}
|
||||
|
||||
public static bool IsAvatarRoot(Transform target)
|
||||
{
|
||||
return ndmf.runtime.RuntimeUtil.IsAvatarRoot(target);
|
||||
}
|
||||
|
||||
public static VRCAvatarDescriptor FindAvatarInParents(Transform target)
|
||||
@ -99,6 +89,11 @@ namespace nadena.dev.modular_avatar.core
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Transform FindAvatarTransformInParents(Transform target)
|
||||
{
|
||||
return ndmf.runtime.RuntimeUtil.FindAvatarInParents(target);
|
||||
}
|
||||
|
||||
public static void MarkDirty(UnityEngine.Object obj)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
@ -154,11 +149,8 @@ namespace nadena.dev.modular_avatar.core
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static bool isPlaying => UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode;
|
||||
#else
|
||||
public static bool isPlaying => true;
|
||||
#endif
|
||||
public static bool isPlaying => ndmf.runtime.RuntimeUtil.IsPlaying;
|
||||
|
||||
public static void InvokeHierarchyChanged()
|
||||
{
|
||||
OnHierarchyChanged?.Invoke();
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "nadena.dev.modular-avatar.core",
|
||||
"references": [
|
||||
"GUID:2665a8d13d1b3f18800f46e256720795"
|
||||
"GUID:2665a8d13d1b3f18800f46e256720795",
|
||||
"GUID:fe747755f7b44e048820525b07f9b956"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@ -105,7 +105,7 @@ namespace modular_avatar_tests.ReplaceObject
|
||||
BuildReport.Clear();
|
||||
Assert.Throws<Exception>(() =>
|
||||
{
|
||||
using (BuildReport.CurrentReport.ReportingOnAvatar(root.GetComponent<VRCAvatarDescriptor>()))
|
||||
using (BuildReport.CurrentReport.ReportingOnAvatar(root))
|
||||
{
|
||||
Process(root);
|
||||
}
|
||||
@ -125,7 +125,7 @@ namespace modular_avatar_tests.ReplaceObject
|
||||
BuildReport.Clear();
|
||||
Assert.Throws<Exception>(() =>
|
||||
{
|
||||
using (BuildReport.CurrentReport.ReportingOnAvatar(root.GetComponent<VRCAvatarDescriptor>()))
|
||||
using (BuildReport.CurrentReport.ReportingOnAvatar(root))
|
||||
{
|
||||
Process(root);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class WorldFixedObjectTest : TestBase
|
||||
var buildContext = new BuildContext(descriptor);
|
||||
buildContext.PluginBuildContext.ActivateExtensionContext<AnimationServicesContext>();
|
||||
|
||||
new WorldFixedObjectProcessor(descriptor).Process(buildContext);
|
||||
new WorldFixedObjectProcessor().Process(buildContext);
|
||||
|
||||
var fixedRoot = avatar.transform.Find("(MA WorldFixedRoot)");
|
||||
var movedFixedObject = avatar.transform.Find("(MA WorldFixedRoot)/FixedObject");
|
||||
@ -46,7 +46,7 @@ public class WorldFixedObjectTest : TestBase
|
||||
var buildContext = new BuildContext(descriptor);
|
||||
buildContext.PluginBuildContext.ActivateExtensionContext<AnimationServicesContext>();
|
||||
|
||||
new WorldFixedObjectProcessor(descriptor).Process(buildContext);
|
||||
new WorldFixedObjectProcessor().Process(buildContext);
|
||||
|
||||
var fixedRoot = avatar.transform.Find("(MA WorldFixedRoot)");
|
||||
var movedFixedObject = avatar.transform.Find("(MA WorldFixedRoot)/FixedObject");
|
||||
|
Loading…
Reference in New Issue
Block a user