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

Unity角色添加Character Controller后移动高速飞离问题咨询

嘿,这个问题我之前用Character Controller的时候也踩过一模一样的坑!角色一移动就飞出去,大概率是你没把移动逻辑和Character Controller的机制对齐,加上重力处理不到位导致的。咱们一步步来解决:

问题根源分析

你遇到的“角色飞离”问题,核心原因通常是这两个:

  1. 移动逻辑冲突:你可能同时混用了Transform直接修改位置(比如Transform.Translate或直接改position)和Character Controller的专属移动方法(Move()/SimpleMove()),两者的物理逻辑会打架,导致角色瞬间被“推飞”。
  2. 重力未正确处理:Character Controller不会自动模拟重力,如果你没手动给角色施加向下的力,角色可能会因为移动逻辑的计算错误,反而向上窜出去。
解决方案

1. 统一用Character Controller的移动方法

立刻停止用Transform相关的移动代码,全部改用CharacterController.Move()来处理角色的所有位移(包括移动、跳跃、重力)。示例代码如下:

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    private CharacterController controller;
    private Vector3 moveDirection;
    public float moveSpeed = 5f;
    public float jumpForce = 8f;
    public float gravity = 20f;

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

    void Update()
    {
        // 地面检测:直接用CharacterController自带的isGrounded属性
        if (controller.isGrounded)
        {
            // 重置移动方向,只处理水平输入
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= moveSpeed;

            // 跳跃逻辑:只有在地面时才能跳
            if (Input.GetButtonDown("Jump"))
            {
                moveDirection.y = jumpForce;
            }
        }

        // 施加重力:每一帧累加向下的重力
        moveDirection.y -= gravity * Time.deltaTime;

        // 执行移动:必须用CharacterController.Move()
        controller.Move(moveDirection * Time.deltaTime);
    }
}

2. 检查Character Controller的参数设置

  • 确保Height和Radius的数值适配你的角色模型,避免角色模型和地面穿模(穿模会导致isGrounded判断异常,进而影响重力和跳跃逻辑)。
  • 不要把Slope Limit设得过高,否则角色可能会在斜面上被“弹飞”。

3. 关于地面检测的补充

你想要的地面检测完全可以通过controller.isGrounded实现,这个属性会自动检测Character Controller底部是否接触到碰撞体,不需要额外给地面加标签。如果需要更精准的检测(比如只检测特定层的地面),可以给地面设置专属Layer,然后配合Physics.Raycast辅助判断,但大部分场景下isGrounded足够用。

额外注意事项
  • 如果你用CharacterController.SimpleMove(),它会自动处理重力,但返回值是角色是否在地面,用法和Move()略有不同,适合简单场景。
  • 所有移动相关的计算一定要乘以Time.deltaTime,保证帧率无关,避免不同设备上移动速度不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:05:32