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