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

添加重力与地面检测后角色无法按设定速度行走奔跑的问题求助

问题修复方案

你的角色移动缓慢的核心问题出在方向空间转换和地面检测位置上,以下是修复后的完整代码及关键修改说明:

修复后的代码

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

public class PlayerMovement : MonoBehaviour
{
    // 移动参数
    [SerializeField] private float walkSpeed = 3f;
    [SerializeField] private float runSpeed = 6f;
    private float currentMoveSpeed;

    private Vector3 moveDirection;
    private Vector3 velocity;

    // 地面检测参数
    [SerializeField] private bool isGrounded;
    [SerializeField] private float groundCheckDistance = 0.2f;
    [SerializeField] private LayerMask groundMask;
    [SerializeField] private float gravity = -9.81f;

    // 组件引用
    private CharacterController controller;

    private void Start()
    {
        controller = GetComponent<CharacterController>();
        // 初始化移动速度为行走速度
        currentMoveSpeed = walkSpeed;
    }

    private void Update()
    {
        Move();
    }

    private void Move()
    {
        // 修正地面检测位置:从CharacterController底部检测,避免误判
        Vector3 groundCheckPos = transform.position + Vector3.down * (controller.height / 2);
        isGrounded = Physics.CheckSphere(groundCheckPos, groundCheckDistance, groundMask);

        if (isGrounded && velocity.y < 0)
        {
            velocity.y = -2f;
        }

        // 获取输入
        float moveX = Input.GetAxis("Horizontal");
        float moveZ = Input.GetAxis("Vertical");

        // 将局部方向转换为世界空间方向(基于相机视角,适配第三人称/第一人称)
        Vector3 cameraForward = Camera.main.transform.forward;
        Vector3 cameraRight = Camera.main.transform.right;
        // 忽略Y轴,保持水平移动
        cameraForward.y = 0;
        cameraRight.y = 0;
        cameraForward.Normalize();
        cameraRight.Normalize();

        // 计算最终移动方向
        moveDirection = cameraForward * moveZ + cameraRight * moveX;
        moveDirection.Normalize(); // 确保斜向移动速度不超过设定值

        if (isGrounded)
        {
            if (moveDirection.magnitude > 0.1f) // 用阈值判断输入,避免浮点精度问题
            {
                if (Input.GetKey(KeyCode.LeftShift))
                {
                    currentMoveSpeed = runSpeed;
                }
                else
                {
                    currentMoveSpeed = walkSpeed;
                }
            }
            else
            {
                currentMoveSpeed = 0; // 静止时速度归0
            }

            // 应用移动速度
            moveDirection *= currentMoveSpeed;
        }

        // 执行移动
        controller.Move(moveDirection * Time.deltaTime);

        // 应用重力
        velocity.y += gravity * Time.deltaTime;
        controller.Move(velocity * Time.deltaTime);
    }
}

关键修改点说明

  • 方向空间转换:原代码直接用局部Z轴创建moveDirection,CharacterController.Move需要世界空间方向,现在改为基于主相机的视角计算移动方向,确保角色朝玩家视角的前后左右移动,同时避免Y轴干扰。
  • 地面检测位置修正:原检测点在transform.position(通常是CharacterController的中心),改为从控制器底部检测,避免角色悬空时误判为地面,或站在地面时误判为空中。
  • 输入判断优化:用moveDirection.magnitude > 0.1f替代moveDirection != Vector3.zero,避免浮点精度导致的判断错误;静止时直接将速度设为0,避免微小输入导致的缓慢移动。
  • 变量命名优化:将原moveSpeed改为currentMoveSpeed,初始化为walkSpeed,避免Inspector未赋值时的初始速度为0的问题。
  • 添加横向移动支持:补充了Horizontal轴输入,适配完整的前后左右移动逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:50:24