Add additional bone proxy validation

Closes: #85
This commit is contained in:
bd_ 2022-11-19 19:12:13 -08:00
parent 999add24c9
commit 4ce3223844
4 changed files with 46 additions and 4 deletions

View File

@ -28,13 +28,20 @@ namespace nadena.dev.modular_avatar.core.editor
{
internal class BoneProxyProcessor
{
internal enum ValidationResult
{
OK,
MovingTarget,
NotInAvatar
}
internal void OnPreprocessAvatar(GameObject avatarGameObject)
{
var boneProxies = avatarGameObject.GetComponentsInChildren<ModularAvatarBoneProxy>(true);
foreach (var proxy in boneProxies)
{
if (proxy.target != null)
if (proxy.target != null && ValidateTarget(avatarGameObject, proxy.target) == ValidationResult.OK)
{
var oldPath = RuntimeUtil.AvatarRootPath(proxy.gameObject);
Transform transform = proxy.transform;
@ -51,5 +58,25 @@ namespace nadena.dev.modular_avatar.core.editor
Object.DestroyImmediate(proxy);
}
}
internal static ValidationResult ValidateTarget(GameObject avatarGameObject, Transform proxyTarget)
{
var avatar = avatarGameObject.transform;
var node = proxyTarget;
while (node != null && node != avatar)
{
if (node.GetComponent<ModularAvatarMergeArmature>() != null ||
node.GetComponent<ModularAvatarBoneProxy>() != null)
{
return ValidationResult.MovingTarget;
}
node = node.parent;
}
if (node == null) return ValidationResult.NotInAvatar;
else return ValidationResult.OK;
}
}
}

View File

@ -55,6 +55,15 @@ namespace nadena.dev.modular_avatar.core.editor
var virtObj = new SerializedObject(objRefs);
var virtProp = virtObj.FindProperty(nameof(TempObjRef.target));
if (virtProp.objectReferenceValue is Transform targetTransform)
{
var validationResult = BoneProxyProcessor.ValidateTarget(parentAvatar, targetTransform);
if (validationResult != BoneProxyProcessor.ValidationResult.OK)
{
EditorGUILayout.HelpBox(S("boneproxy.err." + validationResult), MessageType.Error);
}
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(virtProp, G("boneproxy.target"));
@ -65,7 +74,9 @@ namespace nadena.dev.modular_avatar.core.editor
{
var t = (ModularAvatarBoneProxy) targets[i];
Undo.RecordObjects(targets, "Set targets");
t.target = ((TempObjRef) objRefs[i]).target;
var xform = ((TempObjRef) objRefs[i]).target;
if (RuntimeUtil.FindAvatarInParents(xform)?.gameObject != parentAvatar) continue;
t.target = xform;
}
}
}

View File

@ -45,5 +45,7 @@
"blendshape.mesh": "Mesh",
"blendshape.source": "Source blendshape",
"blendshape.target": "Target blendshape",
"hint.not_in_avatar": "This component needs to be placed inside your avatar to work properly."
"hint.not_in_avatar": "This component needs to be placed inside your avatar to work properly.",
"boneproxy.err.MovingTarget": "You cannot specify a target object that will be moved by other Modular Avatar components",
"boneproxy.err.NotInAvatar": "You must specify an object that is in the avatar"
}

View File

@ -45,5 +45,7 @@
"blendshape.mesh": "メッシュ",
"blendshape.source": "元メッシュのブレンドシェープ",
"blendshape.target": "このメッシュのブレンドシェープ",
"hint.not_in_avatar": "このコンポーネントが正しく動作するには、アバター内に配置する必要があります。"
"hint.not_in_avatar": "このコンポーネントが正しく動作するには、アバター内に配置する必要があります。",
"boneproxy.err.MovingTarget": "他のモジュラーアバターコンポーネントで移動されるオブジェクトを指定できません。",
"boneproxy.err.NotInAvatar": "アバター内のオブジェクトを指定してください。"
}