You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity角色跳跃动画延迟实现:如何在代码中添加起跳延迟?

方案可行性分析与实现步骤

这个方案完全可行!其实很多动作游戏都会采用**「动画先行,逻辑延迟触发」**的设计思路,用来让角色动作更自然,完美匹配动画的发力帧,解决你遇到的「逻辑快于动画」的违和感。

核心思路

按下Space键后,先播放跳跃动画的预备动作,等待0.2秒(对应动画中起跳前的蓄力/抬手帧),再执行物理起跳逻辑,让视觉表现和物理运动完全同步。

具体实现步骤(基于你的代码修改)

1. 动画控制器设置

首先在Unity的Animator窗口中,给你的动画状态机添加一个Trigger类型的参数(命名为JumpTrigger),并设置从Idle/Run状态到跳跃动画状态的过渡条件为这个Trigger(记得关闭过渡的Has Exit Time,避免动画卡顿)。

2. 修改PlayerController代码

我们使用Unity的**协程(Coroutine)**来实现延迟逻辑,它比Invoke更灵活,能方便地添加额外判断(比如延迟期间检查角色是否仍在地面)。修改后的代码如下:

public class PlayerController : MonoBehaviour {
    public float moveSpeed;
    public float jumpForce;
    public CharacterController controller;
    private Vector3 moveDirection;
    public float gravityScale;
    public Animator animator;
    // 新增:跳跃延迟时间,可在Inspector面板直接调整
    public float jumpDelay = 0.2f;
    // 新增:标记是否正在等待跳跃延迟,防止重复触发
    private bool isWaitingForJump = false;

    void Start() {
        controller = GetComponent<CharacterController>();
    }

    void Update() {
        float yStore = moveDirection.y;
        moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
        moveDirection = moveDirection.normalized * moveSpeed;
        moveDirection.y = yStore;

        jump();

        controller.Move(moveDirection * Time.deltaTime);
        animator.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Vertical")));
        // 把isGrounded的设置移到Update里,确保每一帧都更新
        animator.SetBool("isGrounded", controller.isGrounded);
    }

    void jump() {
        if (controller.isGrounded) {
            moveDirection.y = 0f;
            // 只有在地面且未处于延迟等待状态时,才响应跳跃输入
            if (Input.GetButtonDown("Jump") && !isWaitingForJump) {
                // 第一步:触发跳跃动画
                animator.SetTrigger("JumpTrigger");
                // 第二步:启动协程,延迟执行起跳逻辑
                StartCoroutine(DelayedJump());
            }
        } else {
            // 如果角色离开地面,重置等待标记,落地后可再次跳跃
            isWaitingForJump = false;
        }
        moveDirection.y += Physics.gravity.y * gravityScale * Time.deltaTime;
    }

    // 协程:延迟执行起跳的物理逻辑
    IEnumerator DelayedJump() {
        isWaitingForJump = true;
        // 等待设定的延迟时间
        yield return new WaitForSeconds(jumpDelay);
        // 二次检查:确保角色仍在地面,避免延迟期间被碰撞挤开导致空中起跳
        if (controller.isGrounded) {
            moveDirection.y = jumpForce;
            Debug.Log("执行起跳物理逻辑");
        }
        isWaitingForJump = false;
    }
}

3. 关键改动说明

  • 新增jumpDelay参数:可以直接在Inspector面板调整延迟时间,不用修改代码,方便你根据动画节奏微调
  • 新增isWaitingForJump标记:防止玩家在延迟期间重复按跳跃键,导致多次触发起跳逻辑
  • 动画触发优先:按下跳跃键后立刻播放动画,保证视觉反馈及时
  • 协程的二次检查:延迟结束后再次判断角色是否在地面,避免意外情况(比如延迟期间角色被其他物体撞离地面)
  • 优化isGrounded的更新时机:移到Update函数,确保动画状态每一帧都能正确同步

额外注意事项

  • 如果你的跳跃动画包含落地帧,确保动画状态机中从跳跃状态回到Idle/Run状态的过渡条件是isGrounded为true
  • 可以根据你的动画实际长度,微调jumpDelay的值,让起跳逻辑刚好对应动画中角色脚离开地面的那一帧,效果会更完美

内容的提问来源于stack exchange,提问作者RBalconi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:29:49