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

Unity第三人称控制器Bug排查:滑行与刚体不落地问题

第三人称控制器脚本Bug修复

我跟着第三人称控制器教程编写脚本后,遇到两个Bug:

  • 松开W键后角色会像在冰面一样持续滑行
  • 已为角色添加Rigidbody组件,但角色不会下落

以下是我修改后的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class player : MonoBehaviour
{
    public Animator playerAnim;
    public Rigidbody playerRigid;
    public float w_speed, wb_speed, olw_speed, rn_speed, ro_speed;
    public bool walking;
    public Transform playerTrans;

    void FixedUpdate()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            playerRigid.velocity = transform.forward * w_speed * Time.deltaTime;
        }

        if (Input.GetKeyDown(KeyCode.S))
        {
            playerRigid.velocity = -transform.forward * wb_speed * Time.deltaTime;
        }
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            playerAnim.SetTrigger("walk");
            playerAnim.ResetTrigger("idle");
            walking = true;
            //steps1.SetActive(true);
        }
        if (Input.GetKeyUp(KeyCode.W))
        {
            playerAnim.ResetTrigger("walk");
            playerAnim.SetTrigger("idle");
            walking = false;
            //steps1.SetActive(false);
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            playerAnim.SetTrigger("walk");
            playerAnim.ResetTrigger("idle");
            walking = true;
        }
        if (Input.GetKeyUp(KeyCode.S))
        {
            playerAnim.ResetTrigger("walk");
            playerAnim.SetTrigger("idle");
            walking = false;
        }
        if (Input.GetKey(KeyCode.A))
        {
            playerTrans.Rotate(0, -ro_speed * Time.deltaTime, 0);
        }
        if (Input.GetKey(KeyCode.D))
        {
            playerTrans.Rotate(0, ro_speed * Time.deltaTime, 0);
        }
    }
}

问题1:角色滑行的修复

你现在用Input.GetKeyDown设置速度,只会在按键按下瞬间给刚体一个初始速度,之后物理系统的惯性会让角色持续滑动,而且没有在松开按键时重置水平速度。

修复方案:
改用Input.GetKey持续检测按键状态,同时拆分速度分量,只修改水平方向速度,避免覆盖重力影响的垂直速度。修改后的FixedUpdate代码如下:

void FixedUpdate()
{
    float moveInput = 0;
    if (Input.GetKey(KeyCode.W))
    {
        moveInput = 1;
    }
    else if (Input.GetKey(KeyCode.S))
    {
        moveInput = -1;
    }

    // 保留垂直方向的重力速度,只修改水平方向
    Vector3 currentVelocity = playerRigid.velocity;
    if (moveInput != 0)
    {
        float speed = moveInput > 0 ? w_speed : wb_speed;
        currentVelocity.x = transform.forward.x * moveInput * speed;
        currentVelocity.z = transform.forward.z * moveInput * speed;
    }
    else
    {
        // 没有输入时,水平速度归零
        currentVelocity.x = 0;
        currentVelocity.z = 0;
    }
    playerRigid.velocity = currentVelocity;
}

问题2:角色不下落的修复

你的代码每次设置playerRigid.velocity时都直接覆盖了整个向量,包括y轴的速度,这就把重力带来的下落速度给覆盖了,导致角色不会下落。

上面的修复已经解决了这个问题——只修改x、z轴的水平速度,保留y轴的原始速度,让重力正常作用。另外检查Rigidbody的设置:

  • 确认Use Gravity选项已勾选
  • 确认Is Kinematic选项未勾选(勾选后物理系统不会作用于刚体)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:36:29