This commit is contained in:
Dominik G.
2025-10-26 14:26:09 +01:00
parent 40a62b5b5a
commit 96d50bfad5
24 changed files with 4173 additions and 18 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce0d512c11bc70741b2946dfe99bbbc7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -20,7 +20,7 @@ namespace MegaKoop.Game.Networking
private static LobbyGameSceneCoordinator Instance;
public static LobbyGameSceneCoordinator Current => Instance;
[SerializeField] private string characterSceneName = "CharacterScene";
[SerializeField] private string characterSceneName = "SimplePoly City - Low Poly Assets_Demo Scene";
[SerializeField] private float spawnRadius = 3f;
[SerializeField] private float minimumSpawnSpacing = 2.5f;

View File

@@ -3,6 +3,7 @@ using UnityEngine;
namespace MegaKoop.Game
{
[RequireComponent(typeof(UnityEngine.CharacterController))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonCharacterController : MonoBehaviour
{
[Header("Movement")]
@@ -20,15 +21,40 @@ namespace MegaKoop.Game
[Header("Camera Reference")]
[SerializeField] private Transform cameraTransform;
[Header("Animation")]
[SerializeField] private Animator animator;
[SerializeField] private float animationDamping = 0.075f;
[SerializeField] private KeyCode crouchKey = KeyCode.LeftControl;
private UnityEngine.CharacterController characterController;
private Vector3 planarVelocity;
private float verticalVelocity;
private bool isGrounded;
private bool lastGrounded;
private bool isDead;
private MegaKoop.Game.Networking.ICharacterInputSource inputSource;
// Animator parameter hashes
private int hashMoveX;
private int hashMoveZ;
private int hashSpeed;
private int hashIsGrounded;
private int hashIsCrouching;
private int hashIsDead;
private int hashJump;
private bool animatorHashesInitialized;
private void Reset()
{
characterController = GetComponent<UnityEngine.CharacterController>();
animator = GetComponent<Animator>();
InitializeAnimatorHashes();
}
private void Awake()
{
characterController = GetComponent<UnityEngine.CharacterController>();
EnsureAnimatorReference();
if (cameraTransform == null)
{
@@ -38,16 +64,27 @@ namespace MegaKoop.Game
cameraTransform = mainCamera.transform;
}
}
InitializeAnimatorHashes();
isGrounded = characterController.isGrounded;
lastGrounded = isGrounded;
if (isGrounded)
{
verticalVelocity = groundedGravity;
}
}
private void OnEnable()
{
EnsureAnimatorReference();
InitializeAnimatorHashes();
}
private void Update()
{
EnsureAnimatorReference();
InitializeAnimatorHashes();
Vector2 moveInput = ReadMovementInput();
Vector3 desiredMove = CalculateDesiredMove(moveInput);
bool hasMoveInput = desiredMove.sqrMagnitude > 0f;
@@ -69,6 +106,8 @@ namespace MegaKoop.Game
{
verticalVelocity = groundedGravity;
}
UpdateAnimator();
}
public void SetInputSource(MegaKoop.Game.Networking.ICharacterInputSource source)
@@ -188,6 +227,53 @@ namespace MegaKoop.Game
verticalVelocity += gravity * Time.deltaTime;
}
private void UpdateAnimator()
{
if (animator == null) return;
// Use actual CharacterController velocity for accurate animation
Vector3 actualVelocity = characterController.velocity;
Vector3 planarActualVelocity = new Vector3(actualVelocity.x, 0f, actualVelocity.z);
// Calculate movement in local space
Vector3 localVelocity = transform.InverseTransformDirection(planarActualVelocity);
float speed = planarActualVelocity.magnitude;
float denom = Mathf.Max(0.01f, moveSpeed);
float moveX = Mathf.Clamp(localVelocity.x / denom, -1f, 1f);
float moveZ = Mathf.Clamp(localVelocity.z / denom, -1f, 1f);
// Update animator parameters
animator.SetFloat(hashSpeed, speed);
animator.SetFloat(hashMoveX, moveX, animationDamping, Time.deltaTime);
animator.SetFloat(hashMoveZ, moveZ, animationDamping, Time.deltaTime);
animator.SetBool(hashIsGrounded, isGrounded);
// Crouch input (currently only supports local input, can be extended via inputSource)
bool isCrouching = !isDead && Input.GetKey(crouchKey);
animator.SetBool(hashIsCrouching, isCrouching);
// Jump trigger - when leaving ground with upward velocity
if (lastGrounded && !isGrounded && verticalVelocity > 0.1f)
{
animator.ResetTrigger(hashJump);
animator.SetTrigger(hashJump);
}
animator.SetBool(hashIsDead, isDead);
lastGrounded = isGrounded;
}
public void SetDead(bool dead)
{
isDead = dead;
EnsureAnimatorReference();
InitializeAnimatorHashes();
if (animator != null)
{
animator.SetBool(hashIsDead, isDead);
}
}
private void OnValidate()
{
moveSpeed = Mathf.Max(0f, moveSpeed);
@@ -196,6 +282,35 @@ namespace MegaKoop.Game
airControlResponsiveness = Mathf.Max(0f, airControlResponsiveness);
gravity = Mathf.Min(-0.01f, gravity);
groundedGravity = Mathf.Clamp(groundedGravity, gravity, 0f);
animationDamping = Mathf.Max(0f, animationDamping);
EnsureAnimatorReference();
InitializeAnimatorHashes();
}
private void EnsureAnimatorReference()
{
if (animator == null)
{
animator = GetComponent<Animator>();
animatorHashesInitialized = false;
}
}
private void InitializeAnimatorHashes()
{
if (animator == null || animatorHashesInitialized)
{
return;
}
hashMoveX = Animator.StringToHash("MoveX");
hashMoveZ = Animator.StringToHash("MoveZ");
hashSpeed = Animator.StringToHash("Speed");
hashIsGrounded = Animator.StringToHash("IsGrounded");
hashIsCrouching = Animator.StringToHash("IsCrouching");
hashIsDead = Animator.StringToHash("IsDead");
hashJump = Animator.StringToHash("Jump");
animatorHashesInitialized = true;
}
}
}