From d7c2bc78b40d7cc68dd276a89262c6db9867d198 Mon Sep 17 00:00:00 2001 From: pandravrc <162582491+pandravrc@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:01:31 +0900 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8B=95WD=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E5=8B=95=E3=81=8D=E3=82=92=E3=83=96=E3=83=A9=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A5=E3=82=A2=E3=83=83=E3=83=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Pan/NonAAPPart/NonAAPPart.controller | 354 +------------------- Editor/NonAAPPart.cs | 182 +++++----- Editor/PanActionLayer.cs | 2 +- Editor/SplittedAnimation.cs | 32 +- 4 files changed, 132 insertions(+), 438 deletions(-) diff --git a/Assets/Pan/NonAAPPart/NonAAPPart.controller b/Assets/Pan/NonAAPPart/NonAAPPart.controller index 5f4b264..f5adc6a 100644 --- a/Assets/Pan/NonAAPPart/NonAAPPart.controller +++ b/Assets/Pan/NonAAPPart/NonAAPPart.controller @@ -12,15 +12,6 @@ AnimatorStateMachine: - serializedVersion: 1 m_State: {fileID: -4557597298732041500} m_Position: {x: 100, y: 200, z: 0} - - serializedVersion: 1 - m_State: {fileID: 7182687493063219402} - m_Position: {x: 600, y: 200, z: 0} - - serializedVersion: 1 - m_State: {fileID: 8932765688987011974} - m_Position: {x: 600, y: 280, z: 0} - - serializedVersion: 1 - m_State: {fileID: -4643381559086569924} - m_Position: {x: 850, y: 200, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: [] m_EntryTransitions: [] @@ -138,11 +129,11 @@ AnimatorStateMachine: m_ChildStates: - serializedVersion: 1 m_State: {fileID: 6321021897602023970} - m_Position: {x: 50, y: 190, z: 0} + m_Position: {x: 30, y: 200, z: 0} m_ChildStateMachines: - serializedVersion: 1 m_StateMachine: {fileID: -9209389980807788247} - m_Position: {x: 350, y: 190, z: 0} + m_Position: {x: 330, y: 200, z: 0} m_AnyStateTransitions: [] m_EntryTransitions: [] m_StateMachineTransitions: @@ -232,31 +223,6 @@ MonoBehaviour: destMax: 0 localOnly: 0 debugString: ---- !u!1101 &-8017313457632507496 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: - - m_ConditionMode: 2 - m_ConditionEvent: Dummy - m_EventTreshold: 0 - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: 0} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 1 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 0.75 - m_HasExitTime: 0 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &-7961027811418961570 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -378,33 +344,6 @@ MonoBehaviour: destMax: 0 localOnly: 0 debugString: ---- !u!1102 &-7425087842186285559 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Force Exit - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: -364129789767868374} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!1101 &-7208906360442573021 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -461,28 +400,6 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1101 &-6977215187128933726 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: [] - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: -4413599764857911255} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 0 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 1 - m_HasExitTime: 1 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &-6820364207198377827 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -869,11 +786,11 @@ AnimatorStateMachine: m_ChildStates: - serializedVersion: 1 m_State: {fileID: 6333119031731400726} - m_Position: {x: 60, y: 180, z: 0} + m_Position: {x: 30, y: 200, z: 0} m_ChildStateMachines: - serializedVersion: 1 m_StateMachine: {fileID: 4232417910747690239} - m_Position: {x: 360, y: 180, z: 0} + m_Position: {x: 330, y: 200, z: 0} m_AnyStateTransitions: [] m_EntryTransitions: [] m_StateMachineTransitions: @@ -911,33 +828,6 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1102 &-4643381559086569924 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Recovery Tracking - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: 8660748267053479393} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!1102 &-4557597298732041500 AnimatorState: serializedVersion: 6 @@ -964,33 +854,6 @@ AnimatorState: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: ---- !u!1102 &-4413599764857911255 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Recovery Tracking - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: -8017313457632507496} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!1102 &-4383622667153264321 AnimatorState: serializedVersion: 6 @@ -1478,31 +1341,6 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1101 &-364129789767868374 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: - - m_ConditionMode: 2 - m_ConditionEvent: Dummy - m_EventTreshold: 0 - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: 0} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 1 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 0.75 - m_HasExitTime: 0 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &-96462110519689416 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -1542,67 +1380,67 @@ AnimatorController: m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Seated m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: InStation m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: VRCEmote m_Type: 3 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Dummy m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: CN_IS_ACTION_ACTIVE m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: SYNC_CN_TRACKING_RECOVERY_ENABLE m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: SYNC_CN_AFK_LOCOMOTION_ENABLE m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: SYNC_CN_DANCE_GIMMICK_ENABLE m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: CN_IS_ACTION_ACTIVE_FX1 m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: CN_IS_ACTION_ACTIVE_FX2 m_Type: 4 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} m_AnimatorLayers: - serializedVersion: 5 m_Name: EmotePrefab/BodyBlendShape0 @@ -2129,33 +1967,6 @@ MonoBehaviour: blendDuration: 0.5 debugString: outputParamHash: 0 ---- !u!1102 &2814315703749527109 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Recovery standing - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: -6977215187128933726} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!114 &2971274198666466708 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2424,15 +2235,6 @@ AnimatorStateMachine: - serializedVersion: 1 m_State: {fileID: 254149493080176339} m_Position: {x: 100, y: 200, z: 0} - - serializedVersion: 1 - m_State: {fileID: 2814315703749527109} - m_Position: {x: 600, y: 200, z: 0} - - serializedVersion: 1 - m_State: {fileID: -7425087842186285559} - m_Position: {x: 600, y: 280, z: 0} - - serializedVersion: 1 - m_State: {fileID: -4413599764857911255} - m_Position: {x: 850, y: 200, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: [] m_EntryTransitions: [] @@ -2533,28 +2335,6 @@ AnimatorTransition: m_Mute: 0 m_IsExit: 0 serializedVersion: 1 ---- !u!1101 &4514297791931061876 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: [] - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: -4643381559086569924} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 0 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 1 - m_HasExitTime: 1 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &4704642585726803096 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -2663,31 +2443,6 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1101 &5736824695887028055 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: - - m_ConditionMode: 2 - m_ConditionEvent: Dummy - m_EventTreshold: 0 - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: 0} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 1 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 0.75 - m_HasExitTime: 0 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &5882695730673890130 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -3016,33 +2771,6 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1102 &7182687493063219402 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Recovery standing - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: 4514297791931061876} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!1101 &7243961208248905106 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -3239,31 +2967,6 @@ MonoBehaviour: destMax: 0 localOnly: 0 debugString: ---- !u!1101 &8660748267053479393 -AnimatorStateTransition: - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: - m_Conditions: - - m_ConditionMode: 2 - m_ConditionEvent: Dummy - m_EventTreshold: 0 - m_DstStateMachine: {fileID: 0} - m_DstState: {fileID: 0} - m_Solo: 0 - m_Mute: 0 - m_IsExit: 1 - serializedVersion: 3 - m_TransitionDuration: 0 - m_TransitionOffset: 0 - m_ExitTime: 0.75 - m_HasExitTime: 0 - m_HasFixedDuration: 1 - m_InterruptionSource: 0 - m_OrderedInterruption: 1 - m_CanTransitionToSelf: 1 --- !u!1101 &8866490188447635497 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -3289,30 +2992,3 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 ---- !u!1102 &8932765688987011974 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Force Exit - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: - - {fileID: 5736824695887028055} - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 0 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 08c0d1dc3ace5664480d10b08edfd9d3, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: diff --git a/Editor/NonAAPPart.cs b/Editor/NonAAPPart.cs index 3de0a19..6ee20a3 100644 --- a/Editor/NonAAPPart.cs +++ b/Editor/NonAAPPart.cs @@ -23,7 +23,7 @@ public class NonAAPPart VRCAvatarDescriptor AvatarDescriptor; EmotePrefab[] SortedEPs; SplittedAnimation CurrentSplittedAnimation; - AnimatorControllerLayer BlendShape0, NonAAPAnim; + AnimatorControllerLayer Layer_BlendShape0, Layer_NonAAPAnim; AnimatorController NonAAPFX; AnimatorStateMachine CurrentStateMachine; AnimatorState CurrentState; @@ -36,98 +36,109 @@ public NonAAPPart(VRCAvatarDescriptor AvatarDescriptor, EmotePrefab[] SortedEPs) string WorkNonAAPFXPath = $@"{CONST.WORKDIR}NonAAPPart.controller"; AssetDatabase.CopyAsset(CONST.OriginalNonAAPFXPath, WorkNonAAPFXPath); NonAAPFX = AssetDatabase.LoadAssetAtPath(WorkNonAAPFXPath); - BlendShape0 = NonAAPFX.layers.FirstOrDefault(layer => layer.name == "EmotePrefab/BodyBlendShape0"); - NonAAPAnim = NonAAPFX.layers.FirstOrDefault(layer => layer.name == "EmotePrefab/NonAAPPart"); + Layer_BlendShape0 = NonAAPFX.layers.FirstOrDefault(layer => layer.name == "EmotePrefab/BodyBlendShape0"); + Layer_NonAAPAnim = NonAAPFX.layers.FirstOrDefault(layer => layer.name == "EmotePrefab/NonAAPPart"); } public void Run() { - AddBlendShape0State(); for (int i = 0; i < SortedEPs.Length; i++) { CurrentID = i + 1; CurrentEmotePrefab = SortedEPs[i]; - CurrentSplittedAnimation = new SplittedAnimation((AnimationClip)CurrentEmotePrefab.Motion); - AddFX(); + CurrentSplittedAnimation = new SplittedAnimation(AvatarDescriptor.gameObject, (AnimationClip)CurrentEmotePrefab.Motion); + LayerCreate_BlendShape0(); + LayerCreate_NonAAPAnim(); } SetMergeAnimator(); } - private void AddFX() - { - AddBlendShape0(CurrentSplittedAnimation.IsBlendShapeClip); - bool IsOthers = CurrentSplittedAnimation.IsBlendShapeClip || CurrentSplittedAnimation.IsOtherClip; - AddNonAAPAnim(IsOthers); - } - private void AddBlendShape0State() + private void SetMergeAnimator() { - CurrentStateMachine = GetEmoteStateMachine(BlendShape0); - CurrentState = CurrentStateMachine.AddState($@"BlendShape0"); - CurrentState.motion = BodyBlendShape0Anim(); - CurrentState.writeDefaultValues = false; + GameObject TargetObj = new GameObject("EmotePrefabNonAAPPart"); + TargetObj.transform.SetParent(AvatarDescriptor.transform); + var MergeAnimator = TargetObj.AddComponent(); + MergeAnimator.animator = NonAAPFX; + MergeAnimator.pathMode = MergeAnimatorPathMode.Absolute; + MergeAnimator.matchAvatarWriteDefaults = true; + MergeAnimator.layerPriority = 9999999; } - private AnimatorStateMachine GetEmoteStateMachine(AnimatorControllerLayer Target) + + ///BS0-------------------------------- + private void LayerCreate_BlendShape0() //EmoteがBlendShapeを使っているならBlendShape0を上レイヤで実行 { - return Target.stateMachine.stateMachines.FirstOrDefault(sm => sm.stateMachine.name == "Emote").stateMachine; + CurrentStateMachine = GetEmoteStateMachine(Layer_BlendShape0); + if (CurrentSplittedAnimation.IsBlendShapeClip) + { + CurrentState = CurrentStateMachine.AddState($@"E{CurrentID:D3}"); + CurrentState.motion = BodyBlendShape0Anim(CurrentSplittedAnimation.AAPClip); + CurrentState.writeDefaultValues = false; + TransitionFromPrepare(); + TransitionToExit(); + } + else + { + TransitionFromPrepareToForceExit(); + } } - private AnimationClip BodyBlendShape0Anim() + private AnimationClip BodyBlendShape0Anim(AnimationClip referenceClip) //BlendShape0アニメの生成 { SkinnedMeshRenderer BodyMesh = AvatarDescriptor.transform?.Find("Body")?.GetComponent(); AnimationClip clip = new AnimationClip(); clip.wrapMode = WrapMode.ClampForever; + float referenceClipLength = referenceClip.length; int blendShapeCount = BodyMesh.sharedMesh.blendShapeCount; for (int i = 0; i < blendShapeCount; i++) { var name = BodyMesh.sharedMesh.GetBlendShapeName(i); - AnimationCurve curve = AnimationCurve.Constant(0, clip.length, 0); + AnimationCurve curve = AnimationCurve.Constant(0, referenceClipLength, 0); clip.SetCurve("", typeof(SkinnedMeshRenderer), $"blendShape.{name}", curve); } return clip; } - private void AddBlendShape0(bool IsBlandShape) + //Generic-------------------------------- + private AnimatorStateMachine GetEmoteStateMachine(AnimatorControllerLayer Target) { - CurrentStateMachine = GetEmoteStateMachine(BlendShape0); - if (IsBlandShape) - { - CurrentState = GetState("BlendShape0"); - TransitionFromPrepare(); - TransitionToRecovery(); - TransitionToForceExit(); - } - else - { - TransitionFromPrepareToForceExit(); - } + return Target.stateMachine.stateMachines.FirstOrDefault(sm => sm.stateMachine.name == "Emote").stateMachine; + } + public AnimatorState GetState(string name) + { + return CurrentStateMachine.states.FirstOrDefault(s => s.state.name == name).state; } - private void AddNonAAPAnim(bool IsOthers) + private AnimatorStateTransition SetTransition(AnimatorState FromState, AnimatorState ToState, bool hasExitTime, float exitTime, bool hasFixedDuration, float duration, float offset) + { + AnimatorStateTransition transition = FromState.AddTransition(ToState); + transition.hasExitTime = hasExitTime; + transition.exitTime = exitTime; + transition.hasFixedDuration = hasFixedDuration; + transition.duration = duration; + transition.offset = offset; + return transition; + } + private AnimatorState CreateState(string name, AnimationClip clip) + { + AnimatorState animatorState = CurrentStateMachine.AddState(name); + animatorState.motion = clip; + animatorState.writeDefaultValues = false; + return animatorState; + } + + //NONAAPPartレイヤ関連-------------------------------- + private void LayerCreate_NonAAPAnim() //AAPでない部分の定義 { - CurrentStateMachine = GetEmoteStateMachine(NonAAPAnim); + bool IsOthers = CurrentSplittedAnimation.IsBlendShapeClip || CurrentSplittedAnimation.IsOtherClip; + CurrentStateMachine = GetEmoteStateMachine(Layer_NonAAPAnim); if (IsOthers) { CurrentState = CurrentStateMachine.AddState($@"E{CurrentID:D3}"); CurrentState.motion = CurrentSplittedAnimation.NotAAPClip; CurrentState.writeDefaultValues = false; TransitionFromPrepare(); - TransitionToRecovery(); - TransitionToForceExit(); + TransitionToExit(); } else { TransitionFromPrepareToForceExit(); } } - private void SetMergeAnimator() - { - GameObject TargetObj = new GameObject("EmotePrefabNonAAPPart"); - TargetObj.transform.SetParent(AvatarDescriptor.transform); - var MergeAnimator = TargetObj.AddComponent(); - MergeAnimator.animator = NonAAPFX; - MergeAnimator.pathMode = MergeAnimatorPathMode.Absolute; - MergeAnimator.matchAvatarWriteDefaults = true; - MergeAnimator.layerPriority = 9999999; - } - public AnimatorState GetState(string name) - { - return CurrentStateMachine.states.FirstOrDefault(s => s.state.name == name).state; - } private void TransitionFromPrepare() { AnimatorState FromState = GetState("Prepare standing"); @@ -139,60 +150,39 @@ private void TransitionFromPrepare() T.offset = 0; T.AddCondition(AnimatorConditionMode.Equals, CurrentID, "VRCEmote"); } - private void TransitionToRecovery() + private void TransitionToExit() { + var WDState = CreateState($@"WD{CurrentID:D3}", CurrentSplittedAnimation.DefaultValueClip); if (CurrentEmotePrefab.IsOneShot) { - TransitionToRecovery_OneShot(); + SetTransition(CurrentState, WDState, true, 0.75f, true, 0.25f, 0); } else { - TransitionToRecovery_LoopHold(); + SetTransition(CurrentState, WDState, false, 0.75f, true, 0.25f, 0) + .AddCondition(AnimatorConditionMode.NotEqual, CurrentID, "VRCEmote"); } - } - private void TransitionToRecovery_OneShot() - { - AnimatorState ToState = GetState("Recovery standing"); - AnimatorStateTransition T = CurrentState.AddTransition(ToState); - T.hasExitTime = true; - T.exitTime = 0.75f; - T.hasFixedDuration = true; - T.duration = 0.25f; - T.offset = 0; - } - private void TransitionToRecovery_LoopHold() - { - AnimatorState ToState = GetState("Recovery standing"); - AnimatorStateTransition T = CurrentState.AddTransition(ToState); - T.hasExitTime = false; - T.exitTime = 0.75f; - T.hasFixedDuration = true; - T.duration = 0.25f; - T.offset = 0; - T.AddCondition(AnimatorConditionMode.NotEqual, CurrentID, "VRCEmote"); - } - private void TransitionToForceExit() - { - AnimatorState ToState = GetState("Force Exit"); - AnimatorStateTransition T = CurrentState.AddTransition(ToState); - T.hasExitTime = false; - T.exitTime = 0.75f; - T.hasFixedDuration = true; - T.duration = 0; - T.offset = 0; - T.AddCondition(AnimatorConditionMode.If, 0, "Seated"); + SetTransition(CurrentState, WDState, false, 0.75f, true, 0.25f, 0) + .AddCondition(AnimatorConditionMode.If, 0, "Seated"); + + //WDStateで元の状態に戻してからEmoteを終了する + var ExitTransition = WDState.AddExitTransition(); + ExitTransition.hasExitTime = false; + ExitTransition.exitTime = 0f; + ExitTransition.hasFixedDuration = false; + ExitTransition.duration = 0f; + ExitTransition.offset = 0; + ExitTransition.AddCondition(AnimatorConditionMode.IfNot, 0, "Dummy"); } private void TransitionFromPrepareToForceExit() { - AnimatorState FromState = GetState("Prepare standing"); - AnimatorState ToState = GetState("Force Exit"); - AnimatorStateTransition T = FromState.AddTransition(ToState); - T.hasExitTime = false; - T.exitTime = 0; - T.hasFixedDuration = true; - T.duration = 0; - T.offset = 0; - T.AddCondition(AnimatorConditionMode.Equals, CurrentID, "VRCEmote"); + var ExitTransition = GetState("Prepare standing").AddExitTransition(); + ExitTransition.hasExitTime = false; + ExitTransition.exitTime = 0f; + ExitTransition.hasFixedDuration = false; + ExitTransition.duration = 0f; + ExitTransition.offset = 0; + ExitTransition.AddCondition(AnimatorConditionMode.Equals, CurrentID, "VRCEmote"); } } } \ No newline at end of file diff --git a/Editor/PanActionLayer.cs b/Editor/PanActionLayer.cs index 64f0914..7d6a954 100644 --- a/Editor/PanActionLayer.cs +++ b/Editor/PanActionLayer.cs @@ -35,7 +35,7 @@ public void AddEmote(int EmoteID, EmotePrefab EP) { this.CurrentID = EmoteID; this.CurrentEmotePrefab = EP; - CurrentSplittedAnimation = new SplittedAnimation((AnimationClip)EP.Motion); + CurrentSplittedAnimation = new SplittedAnimation(AvatarDescriptor.gameObject, (AnimationClip)EP.Motion); if (EP.IsOneShot) { AddOneShotEmote(); diff --git a/Editor/SplittedAnimation.cs b/Editor/SplittedAnimation.cs index fac32a0..6359b58 100644 --- a/Editor/SplittedAnimation.cs +++ b/Editor/SplittedAnimation.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Runtime.Remoting.Messaging; using UnityEditor; using UnityEngine; @@ -6,11 +7,13 @@ namespace com.github.pandrabox.emoteprefab.editor { public class SplittedAnimation { - public AnimationClip Target, AAPClip, NotAAPClip; + public AnimationClip Target, AAPClip, NotAAPClip, DefaultValueClip; public bool IsBlendShapeClip, IsOtherClip; + GameObject AnimRootObject; - public SplittedAnimation(AnimationClip input) + public SplittedAnimation(GameObject AnimRootObject, AnimationClip input) { + this.AnimRootObject = AnimRootObject; Target = UnityEngine.Object.Instantiate(input) as AnimationClip; AddKeyframesAtEnd(); split(); @@ -40,6 +43,7 @@ private void AddKeyframesAtEnd() } } + public void split() { EditorCurveBinding[] curves = AnimationUtility.GetCurveBindings(Target); @@ -57,6 +61,8 @@ private void CreateClips() RemoveUnwantedCurves(AAPClip, isAAP: true); RemoveUnwantedCurves(NotAAPClip, isAAP: false); + + DefaultValueClip = CreateDefaultValueClip(); } private void RemoveUnwantedCurves(AnimationClip clip, bool isAAP) @@ -73,5 +79,27 @@ private void RemoveUnwantedCurves(AnimationClip clip, bool isAAP) } } } + + + // GameObject AnimRootObjectのAnimatorにNotAAPClipがアタッチされている + // NotAAPClipに含まれる全てのカーブの値を現行の値にした1Fのアニメを作成する + private AnimationClip CreateDefaultValueClip() + { + if (!IsOtherClip && !IsBlendShapeClip) + { + return null; + } + EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(NotAAPClip); + AnimationClip clip = new AnimationClip(); + foreach (EditorCurveBinding binding in bindings) + { + float currentValue; + AnimationUtility.GetFloatValue(AnimRootObject, binding, out currentValue); + Keyframe keyframe = new Keyframe(0, currentValue); + AnimationCurve curve = new AnimationCurve(keyframe); + AnimationUtility.SetEditorCurve(clip, binding, curve); + } + return clip; + } } }