From 94511923d5cf44df5ef4a1604ef20fd0181d1662 Mon Sep 17 00:00:00 2001 From: "Dominik G." Date: Mon, 27 Oct 2025 13:15:34 +0100 Subject: [PATCH] Hotovo animace --- Game/Scripts/Networking/NetworkMessages.cs | 68 +++++++++++++- .../Networking/SteamCharacterNetworkBridge.cs | 91 +++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/Game/Scripts/Networking/NetworkMessages.cs b/Game/Scripts/Networking/NetworkMessages.cs index 527805c..84d5257 100644 --- a/Game/Scripts/Networking/NetworkMessages.cs +++ b/Game/Scripts/Networking/NetworkMessages.cs @@ -15,7 +15,8 @@ namespace MegaKoop.Game.Networking ProjectileImpact = 7, GameState = 8, EnemySpawn = 9, - EnemyDespawn = 10 + EnemyDespawn = 10, + CharacterAnim = 11 } public enum ProjectileImpactKind : byte @@ -108,6 +109,71 @@ namespace MegaKoop.Game.Networking } } + public readonly struct CharacterAnimMessage + { + public readonly int NetworkId; + public readonly float MoveX; + public readonly float MoveZ; + public readonly float Speed; + public readonly float MoveSpeedNormalized; + public readonly bool IsGrounded; + public readonly bool IsCrouching; + public readonly bool IsDead; + public readonly bool IsJumping; + + public CharacterAnimMessage( + int networkId, + float moveX, + float moveZ, + float speed, + float moveSpeedNormalized, + bool isGrounded, + bool isCrouching, + bool isDead, + bool isJumping) + { + NetworkId = networkId; + MoveX = moveX; + MoveZ = moveZ; + Speed = speed; + MoveSpeedNormalized = moveSpeedNormalized; + IsGrounded = isGrounded; + IsCrouching = isCrouching; + IsDead = isDead; + IsJumping = isJumping; + } + + public static byte[] Serialize(CharacterAnimMessage message) + { + using var writer = new NetworkWriter(); + writer.Write(message.NetworkId); + writer.Write(message.MoveX); + writer.Write(message.MoveZ); + writer.Write(message.Speed); + writer.Write(message.MoveSpeedNormalized); + writer.Write(message.IsGrounded); + writer.Write(message.IsCrouching); + writer.Write(message.IsDead); + writer.Write(message.IsJumping); + return writer.ToArray(); + } + + public static CharacterAnimMessage Deserialize(byte[] buffer) + { + using var reader = new NetworkReader(buffer); + int id = reader.ReadInt(); + float moveX = reader.ReadFloat(); + float moveZ = reader.ReadFloat(); + float speed = reader.ReadFloat(); + float moveSpeedNormalized = reader.ReadFloat(); + bool isGrounded = reader.ReadBool(); + bool isCrouching = reader.ReadBool(); + bool isDead = reader.ReadBool(); + bool isJumping = reader.ReadBool(); + return new CharacterAnimMessage(id, moveX, moveZ, speed, moveSpeedNormalized, isGrounded, isCrouching, isDead, isJumping); + } + } + public readonly struct WeaponFireMessage { public readonly int NetworkId; diff --git a/Game/Scripts/Networking/SteamCharacterNetworkBridge.cs b/Game/Scripts/Networking/SteamCharacterNetworkBridge.cs index 2e659fd..76ebe2c 100644 --- a/Game/Scripts/Networking/SteamCharacterNetworkBridge.cs +++ b/Game/Scripts/Networking/SteamCharacterNetworkBridge.cs @@ -8,6 +8,7 @@ namespace MegaKoop.Game.Networking { [Header("References")] [SerializeField] private ThirdPersonCharacterController characterController; + [SerializeField] private Animator animator; [SerializeField] private NetworkIdentity identity; [SerializeField] private Transform rootTransform; [SerializeField] private NetworkCharacterInputProxy networkInputProxy; @@ -70,6 +71,15 @@ namespace MegaKoop.Game.Networking } } + if (animator == null) + { + animator = GetComponent(); + if (animator != null) + { + animator.cullingMode = AnimatorCullingMode.AlwaysAnimate; + } + } + remoteTargetPosition = rootTransform.position; remoteTargetRotation = rootTransform.rotation; } @@ -136,6 +146,7 @@ namespace MegaKoop.Game.Networking networkManager.RegisterHandler(NetworkMessageType.PlayerInput, HandlePlayerInputMessage); networkManager.RegisterHandler(NetworkMessageType.CharacterTransform, HandleCharacterTransformMessage); + networkManager.RegisterHandler(NetworkMessageType.CharacterAnim, HandleCharacterAnimMessage); isRegistered = true; } @@ -148,6 +159,7 @@ namespace MegaKoop.Game.Networking networkManager.UnregisterHandler(NetworkMessageType.PlayerInput, HandlePlayerInputMessage); networkManager.UnregisterHandler(NetworkMessageType.CharacterTransform, HandleCharacterTransformMessage); + networkManager.UnregisterHandler(NetworkMessageType.CharacterAnim, HandleCharacterAnimMessage); isRegistered = false; } @@ -215,6 +227,38 @@ namespace MegaKoop.Game.Networking var message = new CharacterTransformMessage(identity.NetworkId, rootTransform.position, rootTransform.rotation, velocity); byte[] payload = CharacterTransformMessage.Serialize(message); networkManager.SendToAll(NetworkMessageType.CharacterTransform, payload, EP2PSend.k_EP2PSendUnreliableNoDelay); + + BroadcastAnimatorParameters(); + } + + private void BroadcastAnimatorParameters() + { + if (networkManager == null || identity == null || animator == null) + { + return; + } + + float moveX = animator.GetFloat("MoveX"); + float moveZ = animator.GetFloat("MoveZ"); + float speed = animator.GetFloat("Speed"); + float moveSpeedNorm = animator.GetFloat("MoveSpeedNormalized"); + bool isGround = animator.GetBool("IsGrounded"); + bool isCrouch = animator.GetBool("IsCrouching"); + bool isDeadFlag = animator.GetBool("IsDead"); + bool isJump = animator.GetBool("IsJumping"); + + var animMsg = new CharacterAnimMessage( + identity.NetworkId, + moveX, + moveZ, + speed, + moveSpeedNorm, + isGround, + isCrouch, + isDeadFlag, + isJump); + byte[] animPayload = CharacterAnimMessage.Serialize(animMsg); + networkManager.SendToAll(NetworkMessageType.CharacterAnim, animPayload, EP2PSend.k_EP2PSendUnreliableNoDelay); } private void HandlePlayerInputMessage(NetworkMessage message) @@ -267,6 +311,53 @@ namespace MegaKoop.Game.Networking haveRemoteState = true; } + private void HandleCharacterAnimMessage(NetworkMessage message) + { + if (isAuthority) + { + return; + } + + CharacterAnimMessage anim = CharacterAnimMessage.Deserialize(message.Payload); + if (identity != null && anim.NetworkId != identity.NetworkId) + { + if (ownerSteamId != 0 && message.Sender != ownerSteamId) + { + return; + } + + var existing = NetworkIdRegistry.GetById(anim.NetworkId); + if (existing != null && existing != identity) + { + return; + } + + identity.SetNetworkId(anim.NetworkId); + if (identity.NetworkId != anim.NetworkId) + { + return; + } + } + + if (animator == null) + { + animator = GetComponent(); + if (animator == null) + { + return; + } + } + + animator.SetFloat("MoveX", anim.MoveX); + animator.SetFloat("MoveZ", anim.MoveZ); + animator.SetFloat("Speed", anim.Speed); + animator.SetFloat("MoveSpeedNormalized", anim.MoveSpeedNormalized); + animator.SetBool("IsGrounded", anim.IsGrounded); + animator.SetBool("IsCrouching", anim.IsCrouching); + animator.SetBool("IsDead", anim.IsDead); + animator.SetBool("IsJumping", anim.IsJumping); + } + public void SendLocalInput(Vector2 moveInput, bool jump) { if (networkManager == null || identity == null || !isAuthority)