Animace
This commit is contained in:
8
Game/Scripts/Character.meta
Normal file
8
Game/Scripts/Character.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce0d512c11bc70741b2946dfe99bbbc7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user