diff --git a/Assets/BossRoom/Models/Animation Controlers/CharacterSetController.controller b/Assets/BossRoom/Models/Animation Controlers/CharacterSetController.controller index 26bc7adda..0ad2e669c 100644 --- a/Assets/BossRoom/Models/Animation Controlers/CharacterSetController.controller +++ b/Assets/BossRoom/Models/Animation Controlers/CharacterSetController.controller @@ -44,7 +44,7 @@ AnimatorState: m_CycleOffsetParameterActive: 0 m_TimeParameterActive: 0 m_Motion: {fileID: 0} - m_Tag: + m_Tag: BaseNode m_SpeedParameter: m_MirrorParameter: m_CycleOffsetParameter: @@ -754,6 +754,33 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1102 &-5093654682345616202 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: AnticipateMove + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 3599037512052606113} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: -4939085063460368806, guid: 2115c4661f55eff45a5a0f91fc0a12f0, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: --- !u!1102 &-4482486829903005221 AnimatorState: serializedVersion: 6 @@ -954,6 +981,7 @@ AnimatorState: - {fileID: -1751189744513987592} - {fileID: -3322349416516825559} - {fileID: 5808351605165405389} + - {fileID: 5286344766070818967} m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 @@ -964,7 +992,7 @@ AnimatorState: m_CycleOffsetParameterActive: 0 m_TimeParameterActive: 0 m_Motion: {fileID: -8988982740543935465} - m_Tag: + m_Tag: BaseNode m_SpeedParameter: m_MirrorParameter: m_CycleOffsetParameter: @@ -1316,7 +1344,7 @@ AnimatorState: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: NoAttack + m_Name: Nothing m_Speed: 1 m_CycleOffset: 0 m_Transitions: @@ -1336,7 +1364,7 @@ AnimatorState: m_CycleOffsetParameterActive: 0 m_TimeParameterActive: 0 m_Motion: {fileID: 0} - m_Tag: + m_Tag: BaseNode m_SpeedParameter: m_MirrorParameter: m_CycleOffsetParameter: @@ -1401,6 +1429,9 @@ AnimatorStateMachine: - serializedVersion: 1 m_State: {fileID: 7103618770137260043} m_Position: {x: -350, y: 330, z: 0} + - serializedVersion: 1 + m_State: {fileID: -5093654682345616202} + m_Position: {x: 310, y: 330, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: - {fileID: 6300214233644051234} @@ -1490,6 +1521,28 @@ AnimatorState: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: +--- !u!1101 &-97121490881636740 +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: -3516404760485336223} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.62071574 + m_TransitionOffset: 0.00000004339141 + m_ExitTime: 0.0000000041531494 + m_HasExitTime: 1 + m_HasFixedDuration: 0 + m_InterruptionSource: 2 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!91 &9100000 AnimatorController: m_ObjectHideFlags: 0 @@ -1504,139 +1557,145 @@ AnimatorController: m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Attack1 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: HitReact1 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: FallDown m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: StandUp m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: BeginRevive m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Dead m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Attack2 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Emote1 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Emote2 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Emote3 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Emote4 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Trample m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: SkillHeal m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Stunned m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Unstunned m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: ShieldBuffStart m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: ShieldBuffEnd m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: ChargedShotStart m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: ChargedShotEnd m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: EntryFainted m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: EntryDead m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} - m_Name: Buff1 m_Type: 9 m_DefaultFloat: 0 m_DefaultInt: 0 m_DefaultBool: 0 - m_Controller: {fileID: 0} + m_Controller: {fileID: 9100000} + - m_Name: AnticipateMove + m_Type: 9 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} m_AnimatorLayers: - serializedVersion: 5 m_Name: Base Layer @@ -1721,6 +1780,31 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1101 &426919566368059880 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: AnticipateMove + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 7052821593652808675} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.118838675 + m_TransitionOffset: 0 + m_ExitTime: 0.03151326 + m_HasExitTime: 0 + m_HasFixedDuration: 0 + m_InterruptionSource: 2 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!114 &462837921949526196 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2051,6 +2135,28 @@ AnimatorStateMachine: m_ExitPosition: {x: 800, y: 120, z: 0} m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} m_DefaultState: {fileID: -9059899351118470251} +--- !u!1101 &3599037512052606113 +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: -3516404760485336223} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0 + m_TransitionOffset: 0 + m_ExitTime: 0.99473697 + m_HasExitTime: 1 + m_HasFixedDuration: 1 + m_InterruptionSource: 2 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1101 &4047612268588016952 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -2279,6 +2385,31 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1101 &5286344766070818967 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: AnticipateMove + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -5093654682345616202} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0 + m_TransitionOffset: 0 + m_ExitTime: 0.0011970028 + m_HasExitTime: 0 + m_HasFixedDuration: 0 + m_InterruptionSource: 2 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1101 &5537143230144326077 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -2552,6 +2683,33 @@ AnimatorState: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: +--- !u!1102 &7052821593652808675 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: AnticipateMove + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: -97121490881636740} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: -3419257869308726280, guid: 2115c4661f55eff45a5a0f91fc0a12f0, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: --- !u!1102 &7103618770137260043 AnimatorState: serializedVersion: 6 diff --git a/Assets/BossRoom/Scripts/Client/ClickFeedback.cs b/Assets/BossRoom/Scripts/Client/ClickFeedback.cs index 3a73121bf..3cb429a6b 100644 --- a/Assets/BossRoom/Scripts/Client/ClickFeedback.cs +++ b/Assets/BossRoom/Scripts/Client/ClickFeedback.cs @@ -27,12 +27,12 @@ void Start() } m_ClientSender = GetComponent(); - m_ClientSender.OnClientClick += onClick; + m_ClientSender.ClientMoveEvent += onClientMove; m_FeedbackObj = Instantiate(m_FeedbackPrefab); m_FeedbackObj.SetActive(false); } - void onClick(Vector3 position) + void onClientMove(Vector3 position) { position.y += HOVER_HEIGHT; @@ -44,7 +44,7 @@ private void OnDestroy() { if (m_ClientSender) { - m_ClientSender.OnClientClick -= onClick; + m_ClientSender.ClientMoveEvent -= onClientMove; } } } diff --git a/Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacterVisualization.cs b/Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacterVisualization.cs index 8152f418c..14f8bbcb8 100644 --- a/Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacterVisualization.cs +++ b/Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacterVisualization.cs @@ -1,9 +1,8 @@ +using System.Collections.Generic; using BossRoom.Client; using Cinemachine; using MLAPI; using System; -using System.Collections; -using System.ComponentModel; using UnityEngine; namespace BossRoom.Visual @@ -47,6 +46,8 @@ public class ClientCharacterVisualization : NetworkBehaviour int m_FaintedStateTriggerID; int m_DeadStateTriggerID; int m_HitStateTriggerID; + int m_AnticipateMoveTriggerID; + int m_SpeedVariableID; /// public override void NetworkStart() @@ -60,6 +61,8 @@ public override void NetworkStart() m_AliveStateTriggerID = Animator.StringToHash("StandUp"); m_FaintedStateTriggerID = Animator.StringToHash("FallDown"); m_DeadStateTriggerID = Animator.StringToHash("Dead"); + m_AnticipateMoveTriggerID = Animator.StringToHash("AnticipateMove"); + m_SpeedVariableID = Animator.StringToHash("Speed"); m_HitStateTriggerID = Animator.StringToHash(ActionFX.k_DefaultHitReact); m_ActionViz = new ActionVisualization(this); @@ -116,6 +119,11 @@ public override void NetworkStart() m_ActionViz.PlayAction(ref data); gameObject.AddComponent(); m_PartyHUD.SetHeroData(m_NetState); + + if( Parent.TryGetComponent(out ClientInputSender inputSender)) + { + inputSender.ClientMoveEvent += OnMoveInput; + } } else { @@ -124,6 +132,14 @@ public override void NetworkStart() } } + private void OnMoveInput(Vector3 position) + { + if( !IsAnimating ) + { + OurAnimator.SetTrigger(m_AnticipateMoveTriggerID); + } + } + /// /// The switch to certain LifeStates fires an animation on an NPC/PC. This bypasses that initial animation /// and sends an NPC/PC to their eventual looping animation. This is necessary for mid-game player connections. @@ -152,6 +168,11 @@ private void OnDestroy() m_NetState.OnPerformHitReaction -= OnPerformHitReaction; m_NetState.OnStopChargingUpClient -= OnStoppedChargingUp; m_NetState.IsStealthy.OnValueChanged -= OnStealthyChanged; + + if (Parent != null && Parent.TryGetComponent(out ClientInputSender sender)) + { + sender.ClientMoveEvent -= OnMoveInput; + } } } @@ -272,5 +293,24 @@ public void OnAnimEvent(string id) m_ActionViz.OnAnimEvent(id); } + + public bool IsAnimating + { + get + { + if( OurAnimator.GetFloat(m_SpeedVariableID) > 0.0 ) { return true; } + + for( int i = 0; i < OurAnimator.layerCount; i++ ) + { + if (!OurAnimator.GetCurrentAnimatorStateInfo(i).IsTag("BaseNode")) + { + //we are in an active node, not the default "nothing" node. + return true; + } + } + + return false; + } + } } } diff --git a/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs b/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs index 0878bdda4..0a415344d 100644 --- a/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs +++ b/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs @@ -16,7 +16,11 @@ public class ClientInputSender : NetworkBehaviour { private const float k_MouseInputRaycastDistance = 100f; - private const float k_MoveSendRateSeconds = 0.5f; + //The movement input rate is capped at 50ms (or 20 fps). This provides a nice balance between responsiveness and + //upstream network conservation. This matters when holding down your mouse button to move. + private const float k_MoveSendRateSeconds = 0.05f; //20 fps. + + private const float k_TargetMoveTimeout = 0.45f; //prevent moves for this long after targeting someone (helps prevent walking to the guy you clicked). private float m_LastSentMove; @@ -74,7 +78,7 @@ private struct ActionRequest Camera m_MainCamera; - public event Action OnClientClick; + public event Action ClientMoveEvent; /// /// Convenience getter that returns our CharacterData @@ -156,10 +160,10 @@ void FixedUpdate() var ray = m_MainCamera.ScreenPointToRay(Input.mousePosition); if (Physics.RaycastNonAlloc(ray, k_CachedHit, k_MouseInputRaycastDistance, k_GroundLayerMask) > 0) { - // The MLAPI_INTERNAL channel is a reliable sequenced channel. Inputs should always arrive and be in order that's why this channel is used. - m_NetworkCharacter.SendCharacterInputServerRpc(k_CachedHit[0].point); + m_NetworkCharacter.SendCharacterInputServerRpc(k_CachedHit[0].point); + //Send our client only click request - OnClientClick?.Invoke(k_CachedHit[0].point); + ClientMoveEvent?.Invoke(k_CachedHit[0].point); } } } @@ -210,7 +214,8 @@ private void PerformSkill(ActionType actionType, SkillTriggerStyle triggerStyle, if (GetActionRequestForTarget(hitTransform, actionType, triggerStyle, out ActionRequestData playerAction)) { //Don't trigger our move logic for another 500ms. This protects us from moving just because we clicked on them to target them. - m_LastSentMove = Time.time; + m_LastSentMove = Time.time + k_TargetMoveTimeout; + m_NetworkCharacter.RecvDoActionServerRPC(playerAction); } else if(actionType != ActionType.GeneralTarget )