mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 02:35:06 +08:00
MAProbeAnchorの追加(ModularAvatarでAnchorOverrideを設定できるように) (#304)
Co-authored-by: AoiKamishiro <aoi.kamishiro@kamishiro.online>
This commit is contained in:
parent
4e8593845a
commit
7bc29b2ea5
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c217d78c5408b04489548a5823bed3d4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,29 @@
|
||||
using nadena.dev.modular_avatar.core.editor;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace modular_avatar_tests
|
||||
{
|
||||
internal class ProbeAnchorTests : TestBase
|
||||
{
|
||||
[Test]
|
||||
public void TestProbeAnchor()
|
||||
{
|
||||
var prefab = CreatePrefab("ProbeAnchorTests.prefab");
|
||||
AvatarProcessor.ProcessAvatar(prefab);
|
||||
|
||||
var root = prefab.transform.Find("RendererRoot");
|
||||
var target = prefab.transform.Find("ProbeTarget");
|
||||
var obj1 = prefab.transform.Find("RendererRoot/SkinnedMeshRenderer").GetComponent<Renderer>();
|
||||
var obj2 = prefab.transform.Find("RendererRoot/MeshRenderer").GetComponent<Renderer>();
|
||||
var obj3 = prefab.transform.Find("RendererRoot/ParticleSystemRenderer").GetComponent<Renderer>();
|
||||
var obj4 = prefab.transform.Find("RendererRoot/TrailRenderer").GetComponent<Renderer>();
|
||||
|
||||
Assert.AreEqual(target, obj1.probeAnchor);
|
||||
Assert.AreEqual(target, obj2.probeAnchor);
|
||||
Assert.AreEqual(target, obj3.probeAnchor);
|
||||
Assert.AreEqual(target, obj4.probeAnchor);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c3ea8cc803f79c45a629964d7316a3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f3adfcc27e73a249badd8f42ca5a57c
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -198,6 +198,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
new MenuInstallHook().OnPreprocessAvatar(avatarGameObject, context);
|
||||
new MergeArmatureHook().OnPreprocessAvatar(context, avatarGameObject);
|
||||
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
|
||||
new ProbeAnchorProcessor().OnPreprocessAvatar(avatarGameObject);
|
||||
new VisibleHeadAccessoryProcessor(vrcAvatarDescriptor).Process(context);
|
||||
new RemapAnimationPass(vrcAvatarDescriptor).Process(context.AnimationDatabase);
|
||||
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
||||
|
@ -21,6 +21,8 @@ namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
return CheckInternal(bs);
|
||||
case ModularAvatarBoneProxy bp:
|
||||
return CheckInternal(bp);
|
||||
case ModularAvatarProbeAnchor pa:
|
||||
return CheckInternal(pa);
|
||||
case ModularAvatarMenuInstaller mi:
|
||||
return CheckInternal(mi);
|
||||
case ModularAvatarMergeAnimator obj:
|
||||
@ -135,6 +137,19 @@ namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<ErrorLog> CheckInternal(ModularAvatarProbeAnchor pa)
|
||||
{
|
||||
if (pa.probeTarget == null)
|
||||
{
|
||||
return new List<ErrorLog>()
|
||||
{
|
||||
new ErrorLog(ReportLevel.Validation, "validation.probe_anchor.no_target", pa)
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<ErrorLog> CheckInternal(ModularAvatarMenuInstaller mi)
|
||||
{
|
||||
// TODO - check that target menu is in the avatar
|
||||
|
@ -0,0 +1,39 @@
|
||||
using UnityEditor;
|
||||
using static nadena.dev.modular_avatar.core.editor.Localization;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
[CustomEditor(typeof(ModularAvatarProbeAnchor))]
|
||||
[CanEditMultipleObjects]
|
||||
internal class ProbeAnchorEditor : MAEditorBase
|
||||
{
|
||||
private SerializedProperty prop_probeTarget;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
prop_probeTarget = serializedObject.FindProperty(nameof(ModularAvatarProbeAnchor.probeTarget));
|
||||
}
|
||||
|
||||
private void ShowParametersUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(prop_probeTarget, G("probeanchor.target"));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
protected override void OnInnerInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox(S("probe_anchor.help"), MessageType.Info);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
ShowParametersUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
Localization.ShowLanguageUI();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ac49767157d7e142b4b1f277baf00ed
|
||||
timeCreated: 1664757842
|
@ -3,6 +3,7 @@
|
||||
"test0.test_b": "test_b",
|
||||
"boneproxy.foldout.advanced": "Advanced",
|
||||
"boneproxy.target": "Target",
|
||||
"probeanchor.target": "Target",
|
||||
"menuinstall.help.hint_set_menu": "This prefab will be installed to the root menu of your avatar by default. Select a different menu or uncheck the component's enabled checkbox to prevent this.",
|
||||
"menuinstall.help.hint_bad_menu": "Selected menu asset is not part of your avatar.",
|
||||
"menuinstall.installto": "Install To",
|
||||
@ -59,12 +60,14 @@
|
||||
"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",
|
||||
"probeanchor.err.NotInAvatar": "You must specify an object that is in the avatar",
|
||||
"boneproxy.attachment": "Attachment mode",
|
||||
"boneproxy.attachment.AsChildAtRoot": "As child; at root",
|
||||
"boneproxy.attachment.AsChildKeepWorldPose": "As child; keep position and rotation",
|
||||
"boneproxy.attachment.AsChildKeepPosition": "As child; keep position",
|
||||
"boneproxy.attachment.AsChildKeepRotation": "As child; keep rotation",
|
||||
"pb_blocker.help": "This object will not be affected by PhysBones attached to parents.",
|
||||
"probe_anchor.help": "Sets the Anchor Override for the inner renderer object.",
|
||||
"hint.bad_vrcsdk": "Incompatible version of VRCSDK detected.\n\nPlease try upgrading your VRCSDK; if this does not work, check for a newer version of Modular Avatar as well.",
|
||||
"error.stack_trace": "Stack trace (provide this when reporting bugs!)",
|
||||
"error.merge_armature.merge_into_self": "Your Merge Armature component is referencing itself, or a child of itself, as the merge target. You should reference the avatar's armature instead. Do not put Merge Armature on the avatar's main armature.",
|
||||
@ -80,6 +83,7 @@
|
||||
"validation.blendshape_sync.missing_target_renderer": "No renderer found on the target object",
|
||||
"validation.blendshape_sync.missing_target_mesh": "No mesh found on the renderer on the target object",
|
||||
"validation.bone_proxy.no_target": "No target object specified (or target object not found)",
|
||||
"validation.probe_anchor.no_target": "No target object specified (or target object not found)",
|
||||
"validation.menu_installer.no_menu": "No menu to install specified",
|
||||
"validation.merge_animator.no_animator": "No animator to merge specified",
|
||||
"validation.merge_armature.no_target": "No merge target specified",
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"boneproxy.foldout.advanced": "詳細設定",
|
||||
"boneproxy.target": "ターゲット",
|
||||
"probeanchor.target": "ターゲット",
|
||||
"menuinstall.help.hint_set_menu": "このプレハブは自動的にアバターの一番上のメニューに導入されます。不要な場合は別のメニューを指定するか、コンポーネントの有効状態を切ってください。",
|
||||
"menuinstall.help.hint_bad_menu": "選択されたメニューがアバターに紐づけされていません。",
|
||||
"menuinstall.installto": "インストール先",
|
||||
@ -57,12 +58,14 @@
|
||||
"hint.not_in_avatar": "このコンポーネントが正しく動作するには、アバター内に配置する必要があります。",
|
||||
"boneproxy.err.MovingTarget": "他のモジュラーアバターコンポーネントで移動されるオブジェクトを指定できません。",
|
||||
"boneproxy.err.NotInAvatar": "アバター内のオブジェクトを指定してください。",
|
||||
"probeanchor.err.NotInAvatar": "アバター内のオブジェクトを指定してください。",
|
||||
"boneproxy.attachment": "配置モード",
|
||||
"boneproxy.attachment.AsChildAtRoot": "子として・ルートに配置",
|
||||
"boneproxy.attachment.AsChildKeepWorldPose": "子として・ワールド位置と向きを維持",
|
||||
"boneproxy.attachment.AsChildKeepPosition": "子として・ワールド位置を維持",
|
||||
"boneproxy.attachment.AsChildKeepRotation": "子として・ワールド向きを維持",
|
||||
"pb_blocker.help": "このオブジェクトは親のPhysBoneから影響を受けなくなります。",
|
||||
"probe_anchor.help": "このオブジェクトに含まれるレンダラーのAnchorOverrideを設定します。",
|
||||
"hint.bad_vrcsdk": "使用中のVRCSDKのバージョンとは互換性がありません。\n\nVRCSDKを更新してみてください。それでもだめでしたら、Modular Avatarにも最新版が出てないかチェックしてください。",
|
||||
"error.stack_trace": "スタックトレース(バグを報告する時は必ず添付してください!)",
|
||||
"error.merge_armature.merge_into_self": "Merge Armatureに自分自身のオブジェクト、もしくは自分の子をターゲットにしてしています。かわりにアバターのメインArmatureを指定してください。アバター自体のArmatureに追加しないでください。",
|
||||
@ -78,6 +81,7 @@
|
||||
"validation.blendshape_sync.missing_target_renderer": "同期元のオブジェクトにはSkinnedMeshRendererがありません。",
|
||||
"validation.blendshape_sync.missing_target_mesh": "同期元のオブジェクトにはSkinnedMeshRendererがありますが、メッシュがありません。",
|
||||
"validation.bone_proxy.no_target": "ターゲットオブジェクトが未設定、もしくは存在しません。",
|
||||
"validation.probe_anchor.no_target": "ターゲットオブジェクトが未設定、もしくは存在しません。",
|
||||
"validation.menu_installer.no_menu": "インストールするメニューがありません。",
|
||||
"validation.merge_animator.no_animator": "Animator Controllerがありません。",
|
||||
"validation.merge_armature.no_target": "ターゲットオブジェクトが未設定、もしくは存在しません。",
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"boneproxy.foldout.advanced": "高级设置",
|
||||
"boneproxy.target": "目标",
|
||||
"probeanchor.target": "目标",
|
||||
"menuinstall.help.hint_set_menu": "此预制体的菜单默认会安装Avatar的顶部菜单中. 如果不需要, 可以选择其他菜单或取消勾选启用复选框.",
|
||||
"menuinstall.help.hint_bad_menu": "选择的菜单不属于当前Avatar.",
|
||||
"menuinstall.installto": "安装到",
|
||||
@ -52,9 +53,11 @@
|
||||
"hint.not_in_avatar": "此组件需要放置于你的Avatar中才能工作",
|
||||
"boneproxy.err.MovingTarget": "您不能指定将由其他 Modular Avatar 组件移动的目标对象",
|
||||
"boneproxy.err.NotInAvatar": "你必须指定一个在Avatar中的对象",
|
||||
"probeanchor.err.NotInAvatar": "你必须指定一个在Avatar中的对象",
|
||||
"boneproxy.attachment": "附加模式",
|
||||
"boneproxy.attachment.AsChildAtRoot": "作为子对象, 放置于Root",
|
||||
"boneproxy.attachment.AsChildKeepWorldPosition": "作为子对象, 保持原有位置",
|
||||
"pb_blocker.help": "当前对象不会受到附加的父对象的PhysBones的影响.",
|
||||
"probe_anchor.help": "设置此对象所包含的渲染器的AnchorOverride",
|
||||
"hint.bad_vrcsdk": "检测到不兼容的VRCSDK版本.\n\n请尝试升级VRCSDK; 如果这不起作用, 请尝试新版本的Modular Avatar."
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 bd_
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
internal class ProbeAnchorProcessor
|
||||
{
|
||||
internal enum ValidationResult
|
||||
{
|
||||
OK,
|
||||
NotInAvatar
|
||||
}
|
||||
|
||||
internal void OnPreprocessAvatar(GameObject avatarGameObject)
|
||||
{
|
||||
var boneProxies = avatarGameObject.GetComponentsInChildren<ModularAvatarProbeAnchor>(true);
|
||||
|
||||
foreach (var proxy in boneProxies)
|
||||
{
|
||||
BuildReport.ReportingObject(proxy, () => ProcessAnchor(avatarGameObject, proxy));
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessAnchor(GameObject avatarGameObject, ModularAvatarProbeAnchor proxy)
|
||||
{
|
||||
if (proxy.probeTarget.Get(proxy) != null && ValidateTarget(avatarGameObject, proxy.probeTarget.Get(proxy).transform) == ValidationResult.OK)
|
||||
{
|
||||
foreach (Renderer r in proxy.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
r.probeAnchor = proxy.probeTarget.Get(proxy).transform;
|
||||
}
|
||||
}
|
||||
|
||||
Object.DestroyImmediate(proxy);
|
||||
}
|
||||
|
||||
internal static ValidationResult ValidateTarget(GameObject avatarGameObject, Transform proxyTarget)
|
||||
{
|
||||
var avatar = avatarGameObject.transform;
|
||||
var node = proxyTarget;
|
||||
|
||||
while (node != null && node != avatar)
|
||||
{
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
if (node == null) return ValidationResult.NotInAvatar;
|
||||
else return ValidationResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdb66cfc3a147a849810baa9315df90f
|
||||
timeCreated: 1661649405
|
@ -126,6 +126,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
|
||||
SetGizmoIconEnabled(typeof(ModularAvatarBoneProxy), false);
|
||||
SetGizmoIconEnabled(typeof(ModularAvatarProbeAnchor), false);
|
||||
SetGizmoIconEnabled(typeof(ModularAvatarBlendshapeSync), false);
|
||||
SetGizmoIconEnabled(typeof(ModularAvatarMenuInstaller), false);
|
||||
SetGizmoIconEnabled(typeof(ModularAvatarMergeAnimator), false);
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 bd_
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("Modular Avatar/MA Probe Anchor")]
|
||||
public class ModularAvatarProbeAnchor : AvatarTagComponent
|
||||
{
|
||||
public AvatarObjectReference probeTarget;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b18784296c2581e498e5127a23e6f019
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: a8edd5bd1a0a64a40aa99cc09fb5f198, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user