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

Unity开发:如何根据玩家得分动态提升速度等级与物体生成速率

Unity 2D 得分动态调整游戏速度与生成速率的实现逻辑

现有代码存在的问题

  • 硬编码得分阈值和速度倍率,后续调整难度高,新增等级需要手动加if判断
  • 所有滚动对象都在Update中重复执行得分判断,场景内滚动对象较多时会产生不必要的性能损耗
  • 只实现了滚动速度控制,没有涉及物体生成速率的调整逻辑
  • 多if判断没有互斥逻辑,虽然高得分下高倍率会覆盖低倍率,但写法冗余易出错

正确实现逻辑

核心思路是把全局调速逻辑统一放在GameControl单例中,只有得分变化时才重新计算速度等级,再通过事件通知所有需要同步速度的模块,避免每帧重复判断。

1. 改造GameControl单例,新增调速逻辑

把速度等级、得分阈值、生成速率的映射关系统一配置,得分变化时自动计算新参数,对外抛出速度变化事件:

using UnityEngine;

public class GameControl : MonoBehaviour
{
    public static GameControl instance;
    public bool gameOver = false;
    public int score = 0;
    // 基础滚动速度
    public float baseScrollSpeed = -2f;
    // 基础生成间隔(秒)
    public float baseSpawnInterval = 2f;
    
    // 对外暴露的当前参数
    public float currentScrollSpeed { get; private set; }
    public float currentSpawnInterval { get; private set; }
    
    // 速度变化事件,所有需要同步速度的对象都可以订阅
    public delegate void SpeedChangedHandler(float newSpeed, float newSpawnInterval);
    public event SpeedChangedHandler OnSpeedChanged;

    // 速度等级配置:<最低得分要求,速度倍率,生成间隔倍率>
    [System.Serializable]
    public class SpeedLevel
    {
        public int minScore;
        public float speedMultiplier;
        public float spawnIntervalMultiplier;
    }
    // 在Inspector面板配置等级即可,无需改代码
    public SpeedLevel[] speedLevels;

    private void Awake()
    {
        if (instance == null) instance = this;
        else Destroy(gameObject);
    }

    private void Start()
    {
        // 初始化第一级速度
        UpdateSpeedLevel();
    }

    // 得分增加时调用这个方法
    public void AddScore(int add)
    {
        if(gameOver) return;
        score += add;
        // 得分变化后才更新速度等级
        UpdateSpeedLevel();
    }

    private void UpdateSpeedLevel()
    {
        float targetSpeedMulti = 1f;
        float targetSpawnMulti = 1f;
        
        // 找到当前得分对应的最高等级
        foreach (var level in speedLevels)
        {
            if (score >= level.minScore)
            {
                targetSpeedMulti = level.speedMultiplier;
                targetSpawnMulti = level.spawnIntervalMultiplier;
            }
            else
            {
                // 等级按得分从小到大排序的话,到不符合的就可以跳出
                break;
            }
        }

        currentScrollSpeed = baseScrollSpeed * targetSpeedMulti;
        // 生成间隔倍率越小,生成越快
        currentSpawnInterval = baseSpawnInterval * targetSpawnMulti;
        
        // 抛出事件通知所有订阅者
        OnSpeedChanged?.Invoke(currentScrollSpeed, currentSpawnInterval);
    }
}

你可以直接在Inspector面板按从小到大的顺序配置速度等级,比如:

  • 0分:速度倍率1,生成间隔倍率1
  • 5分:速度倍率3,生成间隔倍率0.7
  • 10分:速度倍率5,生成间隔倍率0.4

2. 优化ScrollingObject代码,取消每帧判断

订阅GameControl的速度变化事件,只有速度更新时才修改刚体速度:

using UnityEngine;

public class ScrollingObject : MonoBehaviour
{
    private Rigidbody2D rb2d;

    private void Awake()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    private void OnEnable()
    {
        // 订阅速度变化事件
        GameControl.instance.OnSpeedChanged += UpdateSpeed;
        // 初始化时直接取当前速度
        UpdateSpeed(GameControl.instance.currentScrollSpeed, GameControl.instance.currentSpawnInterval);
    }

    private void OnDisable()
    {
        // 取消订阅避免内存泄漏
        GameControl.instance.OnSpeedChanged -= UpdateSpeed;
    }

    private void UpdateSpeed(float newSpeed, float newSpawnInterval)
    {
        // 游戏结束时不修改速度
        if(GameControl.instance.gameOver) return;
        rb2d.velocity = new Vector2(newSpeed, 0);
    }

    // 单独处理游戏结束逻辑,或者也可以在GameControl抛出游戏结束事件统一处理
    private void Update()
    {
        if (GameControl.instance.gameOver)
        {
            rb2d.velocity = Vector2.zero;
        }
    }
}

3. 新增物体生成速率控制逻辑

在你的场景物体生成脚本中,同样订阅速度变化事件,修改生成间隔即可:

using UnityEngine;

public class ObjectSpawner : MonoBehaviour
{
    // 要生成的物体预设
    public GameObject spawnPrefab;
    private float currentSpawnTimer;
    private float currentSpawnInterval;

    private void OnEnable()
    {
        GameControl.instance.OnSpeedChanged += UpdateSpawnParam;
        currentSpawnInterval = GameControl.instance.currentSpawnInterval;
    }

    private void OnDisable()
    {
        GameControl.instance.OnSpeedChanged -= UpdateSpawnParam;
    }

    private void UpdateSpawnParam(float newSpeed, float newInterval)
    {
        currentSpawnInterval = newInterval;
    }

    private void Update()
    {
        if(GameControl.instance.gameOver) return;
        currentSpawnTimer += Time.deltaTime;
        if (currentSpawnTimer >= currentSpawnInterval)
        {
            currentSpawnTimer = 0;
            Instantiate(spawnPrefab, transform.position, Quaternion.identity);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:54:04