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

Unity3D中如何为已有移动脚本的角色实现跳跃和下蹲功能

Unity CharacterController 跳跃与下蹲功能实现方案

跳跃功能实现要点

  • CharacterController 组件不自带重力模拟,需要自行维护垂直方向速度变量实现下落与跳跃逻辑
  • 新增可配置参数:重力值gravity、跳跃高度jumpHeight,新增私有变量存储垂直速度yVelocity
  • 每帧通过controller.isGrounded判断角色是否接地,接地时将垂直速度置为小负值,避免地面判定异常
  • 检测到跳跃输入(默认Space键)且角色接地时,通过自由落体公式反推初始跳跃速度,实现指定高度的跳跃
  • 每帧将重力叠加到垂直速度,最终合并到controller.Move的位移参数中生效

下蹲功能实现要点

  • 新增可配置参数:下蹲高度crouchHeight、下蹲移速crouchSpeed、下蹲触发键crouchKey,新增私有变量存储站立状态的控制器原始高度、原始移速
  • 按下下蹲键时,直接修改CharacterController的高度为下蹲高度,同步降低移动速度
  • 松开下蹲键时,先通过射线检测角色头顶是否存在障碍物,无遮挡时再还原控制器高度和移速,避免出现穿模问题
  • 可根据项目需求同步修改角色模型缩放、播放下蹲动画,匹配视觉表现

完整修改后的代码

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

public class Movement : MonoBehaviour
{
    public CharacterController controller;
    public Transform cam;
    public float speed = 6f;
    public float turnsmoothT = 0.1f;
    // 跳跃相关参数
    public float gravity = -9.81f;
    public float jumpHeight = 2f;
    // 下蹲相关参数
    public float crouchHeight = 1f;
    public float crouchSpeed = 3f;
    public KeyCode crouchKey = KeyCode.LeftControl;

    float turnsmoothV;
    private float yVelocity;
    private float originalHeight;
    private float originalSpeed;

    void Start()
    {
        // 初始化记录原始高度与移速
        originalHeight = controller.height;
        originalSpeed = speed;
    }

    void Update()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
        bool isGrounded = controller.isGrounded;

        // 接地时重置垂直速度,避免判定异常
        if (isGrounded && yVelocity < 0)
        {
            yVelocity = -2f;
        }

        // 跳跃逻辑
        if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
        {
            yVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
        }

        // 下蹲逻辑
        if (Input.GetKeyDown(crouchKey))
        {
            controller.height = crouchHeight;
            speed = crouchSpeed;
        }
        if (Input.GetKeyUp(crouchKey))
        {
            // 检测头顶是否有障碍物,避免穿模
            bool hasObstacleAbove = Physics.Raycast(transform.position, Vector3.up, originalHeight - controller.height);
            if (!hasObstacleAbove)
            {
                controller.height = originalHeight;
                speed = originalSpeed;
            }
        }

        if (direction.magnitude >= 0.1f)
        {
            float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnsmoothV, turnsmoothT);
            transform.rotation = Quaternion.Euler(0f, angle, 0f);
            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            controller.Move(moveDir.normalized * speed * Time.deltaTime);
        }

        // 应用重力与垂直速度
        yVelocity += gravity * Time.deltaTime;
        controller.Move(Vector3.up * yVelocity * Time.deltaTime);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:27:02