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

Unity制作避障球类游戏时小球提速后抖动、减速、相机无法追踪的求助

Unity躲避类小球运动异常问题排查

问题背景

  • 项目为小球躲避障碍物的休闲游戏,初始设计为每3秒提升一次小球移动速度
  • 已完成基础调试,游戏前期运行正常
  • 已尝试排查项:为所有游戏对象添加物理材质,将摩擦参数全部设为0,抖动问题无改善

异常表现

  • 游戏运行至中途,小球出现高频抖动
  • 小球实际前进速度不升反降
  • 跟随相机无法匹配小球的移动节奏

挂载于小球的PlayerController核心代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour
{
    public Text gameOverText;
    public Text scoreText;
    public bool isGameOver;
    public float speeder;

    public float Score;
    Touch touch;
    public float speedmodifier ;

    public float speed = 5;

    private void Awake()
    {
        isGameOver = false;
        Score = 0;
        if(PlayerPrefs.GetFloat("HighScore") == 0)
        {
            PlayerPrefs.SetFloat("HighScore", 0);
        }
        PlayerPrefs.SetFloat("Score", Score);
    }

    void Start()
    {
        speeder = 4f;
        gameOverText.enabled = false;
        speedmodifier = 0.01f;
    }

    void Update()
    {
        if(speeder >= 0)
        {
            speeder -= Time.deltaTime;
        }
        if (speeder <= 0 && speed < 50)
        {
            speed++;
            speeder = 4f;
        }
        Debug.Log(speed); 

        if (isGameOver == false)
        {
            Score++;
        }
        scoreText.text = "Score : " + Score ;
        
        if (Input.touchCount > 0 && transform.position.x >= -3.5f && transform.position.x <= 3.5f)
        {
            touch = Input.GetTouch(0);
            transform.Translate(touch.deltaPosition.x * speedmodifier, 0, 0);
        }
        else if(transform.position.x > 3.5f)
        {
            transform.position = new Vector3(3.49f, transform.position.y, transform.position.z);
        }
        else if(transform.position.x < -3.5f)
        {
            transform.position = new Vector3(-3.49f, transform.position.y, transform.position.z);
        }
        
        if (Input.GetKey(KeyCode.RightArrow) && transform.position.x < 3.5f)
        {
            transform.Translate(Vector3.right * speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.LeftArrow) && transform.position.x > -3.5f)
        {
            transform.Translate(Vector3.left * speed * Time.deltaTime);
        }

        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.tag == "enemy")
        {
            isGameOver = true;
            StartCoroutine("Wait");
            GetComponent<MeshRenderer>().enabled = false;
            gameObject.GetComponentInChildren<TrailRenderer>().enabled = false;
            gameOverText.enabled = true;

            if(PlayerPrefs.GetFloat("HighScore") < Score)
            {
                PlayerPrefs.SetFloat("HighScore", Score);
                PlayerPrefs.SetFloat("Score", Score);
            }
            else
            {
                PlayerPrefs.SetFloat("Score", Score);
            }
        }
    }

    IEnumerator Wait()
    {
        Debug.Log(" My HighScore is : " + PlayerPrefs.GetFloat("HighScore"));
        Debug.Log(" Score is : " + PlayerPrefs.GetFloat("Score"));
        yield return new WaitForSeconds(3f);
        SceneManager.LoadScene(1);
    }
}

问题根因

  • 运动逻辑与物理管线冲突:所有位移计算全部写在Update()中,且通过Transform.Translate直接修改坐标。当小球速度随时间升高后,单帧位移量变大,直接改坐标的操作会和物理引擎的刚体模拟产生执行顺序冲突,触发抖动;单帧位移量超过碰撞体连续检测阈值时,还会出现碰撞穿透、卡滞,导致实际前进速度下降。
  • 逐帧日志拉低性能:代码在每帧的Update中调用Debug.Log(speed),随着运行时间变长,日志输出量累积,会占用大量主线程性能,导致帧率下降,进而出现移动速度不升反降、相机跟不上的问题。
  • 边界逻辑触发反复强制位移:当小球X坐标超出±3.5范围时,代码每帧都会强制把坐标拉回3.49/-3.49的位置,和横向输入的位移计算叠加时,会让坐标在阈值边界反复横跳,进一步放大抖动。
  • 加速逻辑与设计不符:原设计为每3秒提速一次,实际代码中计时器重置值为4秒,和预期的提速节奏存在偏差。
  • 相机跟随逻辑错配:如果相机是在LateUpdate中跟随Transform的位置,会同步放大Transform的抖动,且固定平滑系数无法适配逐渐升高的移动速度,出现跟不上的问题。

修复方案

  • 所有涉及移动、碰撞的逻辑全部从Update()迁移到FixedUpdate()中执行,匹配物理引擎的固定执行步长
  • 移除所有Transform.Translate的位移调用,改用挂载的Rigidbody组件设置速度的方式控制移动,避免直接修改坐标和物理模拟的冲突
  • 移除运行时的逐帧Debug.Log日志输出,避免不必要的性能开销
  • 边界判定改为在输入位移计算阶段就做范围截断,不在坐标位置上做每帧强制拉回,避免边界抖动
  • 将提速计时器的重置值调整为3f,匹配“每3秒提速一次”的设计
  • 相机跟随改为基于Rigidbody的位置做插值平滑,调整平滑系数适配动态升高的移动速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 13:24:03