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

Unity 2D游戏星星生成异常及ArgumentOutOfRangeException报错求助

Unity 2D星星生成系统问题排查与修复

问题现象

  • 星星出现抽搐、仅在玩家后方生成等异常行为
  • 运行一段时间后抛出ArgumentOutOfRangeException,提示“minValue不能大于maxValue”

问题根源分析

1. 随机数范围逻辑错误

  • starPos.Next(1,4)是左闭右开区间,实际只会生成1、2、3三个值,case4永远不会触发,直接废掉四分之一的生成逻辑
  • FloatRandom方法直接把传入的min和max转整数传给Next(),一旦玩家位置变化导致min > max,就会触发参数异常

2. 生成位置计算逻辑倒置

以case1的x坐标计算为例:10 - player.transform.position.x和14 - player.transform.position.x,当玩家x坐标大于12时,前者数值会比后者大,不仅触发异常,还会导致生成位置完全偏离预期,出现星星只在玩家后方的情况

3. 位置判断与生成逻辑不匹配

isFar判断的是星星与玩家的相对距离,但生成位置用反向计算而非相对偏移,导致生成区域混乱,出现抽搐等异常行为

修复方案

1. 修正随机数逻辑

  • 把starPos.Next(1,4)改成starPos.Next(1,5),让case4能正常触发
  • 在FloatRandom中增加范围校验,若min > max则自动交换,避免参数异常

2. 重构生成位置计算

将生成位置改为基于玩家当前位置的正向偏移,比如玩家右侧x偏移10-14,直接写成player.transform.position.x + 10到player.transform.position.x +14,彻底避免范围倒置问题

3. 简化代码逻辑

优化isFar方法的判断方式,减少冗余代码

修复后的完整代码

using System;
using UnityEngine;

public class SpawnStars : MonoBehaviour
{
    public GameObject starPrefab;
    public GameObject player;
    private Random starPos = new Random();
    private GameObject[] starClones = new GameObject[30];

    private void Start()
    {
        for (int i = 0; i < starClones.Length; i++)
        {
            starClones[i] = StarSpawn();
        }
    }

    void Update()
    {
        for (int i = 0; i < starClones.Length; i++)
        {
            if (starClones[i] != null && IsFar(starClones[i]))
            {
                Destroy(starClones[i]);
                starClones[i] = StarSpawn();
            }
        }
    }

    GameObject StarSpawn()
    {
        float posX, posY;
        int random = starPos.Next(1, 5); // 修正范围,让case4能触发
        switch (random)
        {
            case 1:
                // 玩家右侧区域
                posX = FloatRandom(player.transform.position.x + 10, player.transform.position.x + 14);
                posY = FloatRandom(player.transform.position.y - 10, player.transform.position.y + 11);
                break;
            case 2:
                // 玩家左侧区域
                posX = FloatRandom(player.transform.position.x - 14, player.transform.position.x - 10);
                posY = FloatRandom(player.transform.position.y - 10, player.transform.position.y + 11);
                break;
            case 3:
                // 玩家上方区域
                posX = FloatRandom(player.transform.position.x - 14, player.transform.position.x + 15);
                posY = FloatRandom(player.transform.position.y + 6, player.transform.position.y + 9);
                break;
            case 4:
                // 玩家下方区域
                posX = FloatRandom(player.transform.position.x - 14, player.transform.position.x + 15);
                posY = FloatRandom(player.transform.position.y - 9, player.transform.position.y - 6);
                break;
            default:
                // 兜底逻辑,防止异常
                posX = player.transform.position.x + starPos.Next(-5, 5);
                posY = player.transform.position.y + starPos.Next(-5, 5);
                break;
        }
        return Instantiate(starPrefab, new Vector3(posX, posY, 0), player.transform.rotation);
    }

    bool IsFar(GameObject star)
    {
        Vector2 offset = star.transform.position - player.transform.position;
        return Mathf.Abs(offset.x) >= 15 || Mathf.Abs(offset.y) >= 15;
    }

    float FloatRandom(float min, float max)
    {
        // 确保min <= max,否则交换
        if (min > max)
        {
            (min, max) = (max, min);
        }
        // 处理边界情况,避免Next参数相同
        if (Math.Abs(min - max) < 0.01f)
        {
            return min;
        }
        int minInt = Convert.ToInt32(min * 100);
        int maxInt = Convert.ToInt32(max * 100);
        float random = starPos.Next(minInt, maxInt);
        return random / 100f;
    }
}

额外优化建议

  • 直接用Unity自带的Random.Range()替代自定义的FloatRandom,Unity原生方法支持浮点数,还会自动处理min>max的情况,代码更简洁
  • 引入对象池技术,复用星星对象,减少频繁Destroy/Instantiate带来的性能开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 06:06:21