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

Unity开发:修改C#控制脚本后角色无法跳跃仅能左右移动

问题诱因

核心问题出在接地检测逻辑完全失效,叠加代码冗余和配置缺失,最终导致移动/跳跃异常:

  • 代码未给Physics.OverlapSphere配置碰撞层掩码,检测范围默认包含玩家自身的碰撞体,导致返回的碰撞体数量永远包含玩家自身,无法准确判断是否接触地面。
  • 接地判断条件写反:当前代码逻辑是「检测到1个碰撞体就直接终止FixedUpdate执行,跳过后续跳跃逻辑」,如果地面检测点放在玩家碰撞体内部,会导致站在地面时永远触发return,跳跃输入永远不会被处理,仅能执行return前的水平移动逻辑。
  • 若把判断条件改回Length == 0,由于检测永远会碰到玩家自身碰撞体,返回长度永远≥1,会导致物理速度赋值逻辑和刚体重力/碰撞解算冲突,最终角色完全无法移动。
  • FixedUpdate中存在冗余的速度重复赋值代码,会干扰跳跃力的施加效果。
修复方案

按照以下步骤调整即可恢复正常控制:

  • 分层配置碰撞层:将玩家对象设置到单独的Player层,地面/可站立平台设置到Ground层,避免自检。
  • 调整地面检测点位置:将groundCheckTransform放在角色胶囊碰撞体的脚底正下方,稍微露出碰撞体边缘,确保0.1半径的检测球站在地面时能刚好碰到地面碰撞体,跳起后脱离地面。
  • 修正代码逻辑:给接地检测加层过滤,修正判断条件,删除冗余的速度赋值,修复跳跃标志位异常缓存问题。

修复后的完整代码如下:

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

public class Player : MonoBehaviour
{
    [SerializeField] private Transform groundCheckTransform = null;
    // 配置地面层掩码,在Inspector中选择Ground层即可
    [SerializeField] private LayerMask groundMask;
    private bool jumpKeyWasPressed;
    private float horizontalInput;
    private Rigidbody rigidbodyComponent;
    private readonly float jumpForce = 5f;
    private readonly float groundCheckRadius = 0.1f;

    // Start is called before the first frame update
    void Start()
    {
        rigidbodyComponent = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            jumpKeyWasPressed = true;
        }
        horizontalInput = Input.GetAxis("Horizontal");
    }

    //Fixed update is called every physics update
    private void FixedUpdate()
    {
        // 仅保留一次水平速度赋值
        rigidbodyComponent.velocity = new Vector3(horizontalInput, rigidbodyComponent.velocity.y, 0);
        
        // 接地检测:只检测地面层,排除自身
        bool isGrounded = Physics.OverlapSphere(groundCheckTransform.position, groundCheckRadius, groundMask).Length > 0;
        
        // 空中不允许跳跃,重置跳跃标志避免落地自动跳
        if (!isGrounded)
        {
            jumpKeyWasPressed = false;
            return;
        }

        // 接地状态才响应跳跃输入
        if (jumpKeyWasPressed)
        {
            rigidbodyComponent.AddForce(Vector3.up * jumpForce, ForceMode.VelocityChange);
            jumpKeyWasPressed = false;
        }
    }
}
  • 回到Unity编辑器,选中玩家对象,在Player组件的Inspector面板中,把Ground Mask字段勾选为你之前设置的地面层即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:42:40