update di chuyển debug jump
This commit is contained in:
@@ -9,46 +9,153 @@ namespace OnlyScove.Scripts
|
||||
[SerializeField] private string speedParamName = "Speed";
|
||||
[SerializeField] private string velocityXParamName = "Velocity X";
|
||||
[SerializeField] private string velocityZParamName = "Velocity Z";
|
||||
[SerializeField] private string groundedParamName = "Grounded";
|
||||
[SerializeField] private float animationDamping = 0.2f;
|
||||
|
||||
[Header("Visual Correction")]
|
||||
[SerializeField] private float visualOffsetY = 0f;
|
||||
[SerializeField] private Transform modelTransform;
|
||||
private CharacterController controller;
|
||||
|
||||
private Animator anim;
|
||||
private int speedHash;
|
||||
private int velocityXHash;
|
||||
private int velocityZHash;
|
||||
private bool hasSpeedParam;
|
||||
private bool hasVelocityXParam;
|
||||
private bool hasVelocityZParam;
|
||||
private int groundedHash;
|
||||
|
||||
private readonly System.Collections.Generic.HashSet<int> parameterHashes = new System.Collections.Generic.HashSet<int>();
|
||||
|
||||
public void Initialize(Animator animator)
|
||||
{
|
||||
this.anim = animator;
|
||||
this.controller = GetComponentInParent<CharacterController>();
|
||||
|
||||
// Auto-assign modelTransform if null
|
||||
if (modelTransform == null && anim != null) modelTransform = anim.transform;
|
||||
|
||||
if (anim != null)
|
||||
{
|
||||
Debug.Log($"<color=green>[AnimationHandler]</color> Animator found on: {anim.gameObject.name}");
|
||||
parameterHashes.Clear();
|
||||
foreach (AnimatorControllerParameter param in anim.parameters)
|
||||
{
|
||||
if (param.name == speedParamName) hasSpeedParam = true;
|
||||
if (param.name == velocityXParamName) hasVelocityXParam = true;
|
||||
if (param.name == velocityZParamName) hasVelocityZParam = true;
|
||||
parameterHashes.Add(param.nameHash);
|
||||
}
|
||||
|
||||
int speedHashCheck = Animator.StringToHash(speedParamName);
|
||||
if (!parameterHashes.Contains(speedHashCheck) && parameterHashes.Contains(Animator.StringToHash("Blend")))
|
||||
{
|
||||
speedParamName = "Blend";
|
||||
speedHash = Animator.StringToHash(speedParamName);
|
||||
Debug.Log($"<color=yellow>[AnimationHandler]</color> 'Speed' not found, using 'Blend' instead.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("<color=red>[AnimationHandler]</color> FAILED to find Animator! Please check your Prefab.");
|
||||
}
|
||||
|
||||
speedHash = Animator.StringToHash(speedParamName);
|
||||
velocityXHash = Animator.StringToHash(velocityXParamName);
|
||||
velocityZHash = Animator.StringToHash(velocityZParamName);
|
||||
groundedHash = Animator.StringToHash(groundedParamName);
|
||||
}
|
||||
|
||||
public void UpdateAnimator(float speed, Vector2 moveInput, float deltaTime)
|
||||
private bool wasGroundedInAnimator;
|
||||
|
||||
public void UpdateAnimator(float speed, Vector2 moveInput, bool isGrounded, float deltaTime)
|
||||
{
|
||||
if (anim == null) return;
|
||||
|
||||
if (hasSpeedParam) anim.SetFloat(speedHash, speed, animationDamping, deltaTime);
|
||||
if (hasVelocityXParam) anim.SetFloat(velocityXHash, moveInput.x * speed, animationDamping, deltaTime);
|
||||
if (hasVelocityZParam) anim.SetFloat(velocityZHash, moveInput.y * speed, animationDamping, deltaTime);
|
||||
// Snap to zero if speed is very low to force Idle
|
||||
float targetSpeed = speed < 0.05f ? 0f : speed;
|
||||
float damping = (targetSpeed == 0f || targetSpeed > 0.9f) ? 0f : animationDamping;
|
||||
|
||||
if (parameterHashes.Contains(speedHash)) anim.SetFloat(speedHash, targetSpeed, damping, deltaTime);
|
||||
if (parameterHashes.Contains(velocityXHash)) anim.SetFloat(velocityXHash, moveInput.x * targetSpeed, damping, deltaTime);
|
||||
if (parameterHashes.Contains(velocityZHash)) anim.SetFloat(velocityZHash, moveInput.y * targetSpeed, damping, deltaTime);
|
||||
|
||||
// Quan trọng: Cập nhật biến Grounded cho Animator
|
||||
if (parameterHashes.Contains(groundedHash)) anim.SetBool(groundedHash, isGrounded);
|
||||
|
||||
// Nếu đang ở trên mặt đất, đảm bảo reset các trạng thái nhảy/rơi
|
||||
if (isGrounded)
|
||||
{
|
||||
SafeSetBool("IsJumping", false);
|
||||
SafeSetBool("IsFalling", false);
|
||||
|
||||
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
|
||||
if (stateInfo.IsName("Jump") || stateInfo.IsName("Fall") || stateInfo.IsName("Airborne"))
|
||||
{
|
||||
anim.CrossFadeInFixedTime("Locomotion Ground", 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
wasGroundedInAnimator = isGrounded;
|
||||
}
|
||||
|
||||
public void SafeSetTrigger(string name)
|
||||
{
|
||||
if (anim == null) return;
|
||||
int hash = Animator.StringToHash(name);
|
||||
if (parameterHashes.Contains(hash)) anim.SetTrigger(hash);
|
||||
}
|
||||
|
||||
public void SafeSetTrigger(int hash)
|
||||
{
|
||||
if (anim == null) return;
|
||||
if (parameterHashes.Contains(hash)) anim.SetTrigger(hash);
|
||||
}
|
||||
|
||||
public void SafeResetTrigger(string name)
|
||||
{
|
||||
if (anim == null) return;
|
||||
int hash = Animator.StringToHash(name);
|
||||
if (parameterHashes.Contains(hash)) anim.ResetTrigger(hash);
|
||||
}
|
||||
|
||||
public void SafeResetTrigger(int hash)
|
||||
{
|
||||
if (anim == null) return;
|
||||
if (parameterHashes.Contains(hash)) anim.ResetTrigger(hash);
|
||||
}
|
||||
|
||||
public void SafeSetBool(string name, bool value)
|
||||
{
|
||||
if (anim == null) return;
|
||||
int hash = Animator.StringToHash(name);
|
||||
if (parameterHashes.Contains(hash)) anim.SetBool(hash, value);
|
||||
}
|
||||
|
||||
public void SafeSetFloat(int hash, float value, float dampTime, float deltaTime)
|
||||
{
|
||||
if (anim == null) return;
|
||||
if (parameterHashes.Contains(hash)) anim.SetFloat(hash, value, dampTime, deltaTime);
|
||||
}
|
||||
|
||||
public void SetSpeed(float speed)
|
||||
{
|
||||
if (anim != null && hasSpeedParam) anim.SetFloat(speedHash, speed);
|
||||
if (anim != null && parameterHashes.Contains(speedHash))
|
||||
anim.SetFloat(speedHash, speed);
|
||||
}
|
||||
|
||||
public void ForceLocomotion()
|
||||
{
|
||||
if (anim != null) anim.CrossFadeInFixedTime("Locomotion Ground", 0.1f);
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (modelTransform != null && controller != null)
|
||||
{
|
||||
// Automatically snap mesh to the bottom of the CharacterController capsule
|
||||
// This fixes hovering/tiptoeing issues regardless of animation offsets
|
||||
Vector3 targetPos = modelTransform.localPosition;
|
||||
float bottomY = controller.center.y - (controller.height / 2f);
|
||||
targetPos.y = bottomY + visualOffsetY;
|
||||
|
||||
modelTransform.localPosition = targetPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user