You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity 2D平台游戏新手求助:如何创建优质角色控制器?

打造优质Unity 2D平台跳跃角色控制器的实用技巧

Hey there! 作为刚上手Unity 2D平台跳跃开发的新手,你已经迈出了超棒的第一步——搭好基础地图和玩家对象,连核心脚本的变量都定义到位了。接下来咱们一步步把这个角色控制器打磨得更丝滑、更符合平台跳跃游戏的手感👇

一、基础移动的优化:让角色跑起来更自然

首先是移动输入的处理,别直接用键盘按键的布尔值,改用Input.GetAxis("Horizontal"),它不仅支持键盘的A/D、左/右键,还能适配手柄输入,而且自带平滑过渡,不会让角色动作显得生硬。

另外,空中移动的灵敏度可以适当降低,模拟现实中空中操控力减弱的感觉,提升真实感:

private void Update() {
    float horizontalInput = Input.GetAxis("Horizontal");
    // 地面时用正常速度,空中降低灵敏度
    float currentMoveSpeed = isGrounded ? speed : speed * 0.6f;
    // 只修改X轴速度,保留Y轴的重力影响
    body.velocity = new Vector2(horizontalInput * currentMoveSpeed, body.velocity.y);

    // 根据移动方向翻转Sprite,不用做两个方向的动画
    if (horizontalInput != 0) {
        spriteRenderer.flipX = horizontalInput < 0;
    }
}

二、跳跃机制:手感的核心

你的脚本里已经有raycastPoint用来检测地面,这一步很关键,但咱们可以把地面检测做得更严谨,再加上两个提升手感的小机制:

1. 精准的地面检测

一定要给地面单独设置一个Layer(比如命名为"Ground"),用LayerMask过滤检测对象,避免射线误触玩家自身或其他道具:

private bool isGrounded;
[SerializeField] private LayerMask groundLayer;

private void Update() {
    // 射线长度设为0.02f,比raycastPoint的位置稍长一点,避免漏判地面
    RaycastHit2D hit = Physics2D.Raycast(
        raycastPoint.transform.position, 
        Vector2.down, 
        0.02f, 
        groundLayer
    );
    isGrounded = hit.collider != null;
}

2. 跳跃缓冲(Jump Buffer)

玩家经常会在即将落地前提前按跳跃,这时候如果直接忽略输入,手感会很差。加入跳跃缓冲,记录最后一次按下跳跃的时间,在落地后的短时间内依然能触发跳跃:

private float jumpBufferTime = 0.1f;
private float lastJumpInputTime;

private void Update() {
    // 记录跳跃输入的时间
    if (Input.GetButtonDown("Jump")) {
        lastJumpInputTime = Time.time;
    }

    // 地面检测逻辑...

    // 判断是否在缓冲时间内且落地
    if (isGrounded && Time.time - lastJumpInputTime < jumpBufferTime) {
        body.velocity = new Vector2(body.velocity.x, jump);
        lastJumpInputTime = 0; // 重置避免重复触发
    }
}

3. 郊狼时间(Coyote Time)

这是平台跳跃游戏的经典手感优化:玩家刚离开地面的短时间内,依然允许跳跃,模拟现实中踩空瞬间还能补救的感觉,大大降低操作门槛:

private float coyoteTime = 0.1f;
private float lastGroundedTime;

private void Update() {
    // 地面检测逻辑...
    if (isGrounded) {
        lastGroundedTime = Time.time;
    }

    // 即使刚离开地面,只要在郊狼时间内按下跳跃依然有效
    if (Input.GetButtonDown("Jump") && Time.time - lastGroundedTime < coyoteTime) {
        body.velocity = new Vector2(body.velocity.x, jump);
    }
}

三、状态判断与动画衔接:让角色活起来

你的脚本里已经有Animator,现在要给它设置对应的参数(比如SpeedIsGroundedIsJumpingIsFalling),然后在代码里实时更新这些参数,让动画自动跟随角色状态切换:

private void Update() {
    // 移动、跳跃逻辑...

    // 更新动画参数
    animator.SetFloat("Speed", Mathf.Abs(body.velocity.x));
    animator.SetBool("IsGrounded", isGrounded);
    animator.SetBool("IsJumping", body.velocity.y > 0 && !isGrounded);
    animator.SetBool("IsFalling", body.velocity.y < 0 && !isGrounded);
}

这样角色移动时播放跑步动画,跳跃时播放起跳动画,下落时播放下落动画,整体观感会流畅很多。

四、额外的细节优化

  • 调整重力参数:你当前Rigidbody2D的重力Scale设为50,这个值偏大,会导致角色下落过快,手感偏硬。可以尝试调到10-20之间,根据你想要的游戏风格慢慢调试。
  • 平滑减速:在地面时可以用Mathf.Lerp来平滑速度变化,让角色停止时更自然,不会突然刹住:
body.velocity = new Vector2(
    Mathf.Lerp(body.velocity.x, horizontalInput * currentMoveSpeed, 0.1f), 
    body.velocity.y
);
  • 斜坡处理:如果你的地图有斜坡,可以在地面检测时判断地面法线的角度,当角度大于45度时,限制角色的移动速度,避免角色在斜坡上滑动或失控。

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

火山引擎 最新活动