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

Unity仿Subway Surfer游戏切换Lane后角色抖动问题求助

解决Subway Surfer类游戏车道切换时角色抖动的问题

嘿,我仔细看了你的代码,角色切换车道时抖动的问题主要出在目标位置计算错误和X轴移动的平滑处理方式不对这两点上,咱们一步步来搞定它:

1. 目标位置计算逻辑错误

你原来的代码里,目标位置的初始化是这么写的:

Vector3 targetPosition = transform.position.z * Vector3.forward;

这会得到一个(0, 0, transform.position.z)的向量,然后再加上左右偏移。但实际上咱们需要保持角色当前的Y、Z位置不变,只把X轴调整到对应车道的位置——中间车道(desiredLane=1)X为0,左车道(0)X为-LANE_DISTANCE,右车道(2)X为LANE_DISTANCE。

正确的目标位置计算应该是:

Vector3 targetPosition = new Vector3(
    (desiredLane - 1) * LANE_DISTANCE, 
    transform.position.y, 
    transform.position.z
);

这样就能精准定位到目标车道的X坐标,不会出现位置偏移的问题。

2. X轴移动的平滑处理方式不对

原来的代码用(targetPosition - transform.position).normalized.x * speed计算X方向速度,这种方式在角色接近目标位置时,会因为normalized(归一化)导致X方向的速度忽大忽小,再加上你的speed一直在递增,就很容易引发抖动。

咱们换成更平稳的移动方式:用Mathf.MoveTowards来让角色平滑滑向目标X坐标,这样速度会均匀变化,不会出现来回调整的情况。代码改成这样:

// 先定义一个车道切换的平滑速度(可以根据手感调整)
private float smoothLaneSpeed = 15f;

// 在Update里计算X方向移动
float targetX = Mathf.MoveTowards(transform.position.x, targetPosition.x, smoothLaneSpeed * Time.deltaTime);
moveVector.x = (targetX - transform.position.x) / Time.deltaTime;

3. 额外的优化点

  • 你在Update里重新声明了局部变量Vector3 moveVector,虽然不影响功能,但会覆盖类里的同名成员变量,建议删掉局部声明,直接用类里的moveVector。
  • 原来的TURN_SPEED = 0.05f太小了,角色转向会很慢,看起来卡顿,建议改成0.2f左右,让转向更流畅。
  • 你原来的代码里没有处理verticalVelocity的更新(重力和跳跃逻辑),这可能导致角色悬空或者跳跃异常,我在下面的完整代码里补充了这部分,记得加上。

修改后的完整Update方法

void Update () {
    // 速度递增逻辑保持不变
    if(Time.time - speedIncreasLastTick > speedIncreaseTime) {
        speedIncreasLastTick = Time.time;
        speed += speedIncreaseAmount;
    }

    // 车道切换输入
    if (Input.GetKeyDown(KeyCode.LeftArrow)) MoveLane (false);
    if (Input.GetKeyDown(KeyCode.RightArrow)) MoveLane (true);

    // 正确计算目标位置
    Vector3 targetPosition = new Vector3(
        (desiredLane - 1) * LANE_DISTANCE, 
        transform.position.y, 
        transform.position.z
    );

    // 初始化移动向量
    moveVector = Vector3.zero;

    // 平滑处理X轴车道切换
    float targetX = Mathf.MoveTowards(transform.position.x, targetPosition.x, smoothLaneSpeed * Time.deltaTime);
    moveVector.x = (targetX - transform.position.x) / Time.deltaTime;

    // 重力与跳跃处理(补充你缺失的部分)
    if (controller.isGrounded) {
        verticalVelocity = -0.1f; // 轻微接地力,防止角色悬空
        if(Input.GetKeyDown(KeyCode.Space)){
            verticalVelocity = jumpForce;
        }
    } else {
        verticalVelocity -= gravity * Time.deltaTime;
    }
    moveVector.y = verticalVelocity;

    // Z轴前进速度
    moveVector.z = speed;

    // 移动角色
    controller.Move(moveVector * Time.deltaTime);

    // 平滑转向
    Vector3 dir = controller.velocity;
    if (dir != Vector3.zero) {
        dir.y = 0;
        transform.forward = Vector3.Lerp (transform.forward, dir.normalized, 0.2f);
    }
}

记得在你的类里加上smoothLaneSpeed的定义:

private float smoothLaneSpeed = 15f;

这样修改后,角色切换车道时就会平稳滑动,不会再出现抖动的情况啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:27:13