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

Unity场景中实现无需手动触发的瓶子随机出现功能

Unity自动随机触发瓶子出现的解决方案

先优化原代码的随机数问题

原代码每次调用randomCounter()时都新建System.Random实例,短时间内多次调用可能生成重复随机数。建议将Random实例作为类成员初始化,避免重复创建:

public class RandomBottleAppearance : MonoBehaviour
{
    public GameObject bottleOne;
    private System.Random _ranGen; // 类成员存储Random实例

    void Awake()
    {
        _ranGen = new System.Random(); // 在Awake中初始化一次
    }

    private int RandomCounter()
    {
        int ranNum = _ranGen.Next(1, 20);
        Debug.Log($"随机数生成:{ranNum}");
        return ranNum;
    }

    private void RandomInvoke()
    {
        // 移除冗余判断,activeSelf本身只能是true/false
        bottleOne.SetActive(RandomCounter() == 4);
    }
}

方法一:使用Unity内置的InvokeRepeating自动触发

InvokeRepeating是Unity内置的重复调用方法,可指定首次触发延迟和后续重复间隔,取消触发只需调用CancelInvoke。

完整代码示例:

public class RandomBottleAppearance : MonoBehaviour
{
    public GameObject bottleOne;
    public float initialDelay = 1f; // 首次触发的延迟时间
    public float repeatInterval = 2f; // 每次触发的间隔时间
    private System.Random _ranGen;

    void Awake()
    {
        _ranGen = new System.Random();
    }

    void Start()
    {
        // 启动自动重复调用
        InvokeRepeating(nameof(RandomInvoke), initialDelay, repeatInterval);
    }

    private int RandomCounter()
    {
        int ranNum = _ranGen.Next(1, 20);
        Debug.Log($"随机数生成:{ranNum}");
        return ranNum;
    }

    private void RandomInvoke()
    {
        bottleOne.SetActive(RandomCounter() == 4);
    }

    // 外部调用此方法可取消自动触发
    public void StopAutoTrigger()
    {
        CancelInvoke(nameof(RandomInvoke));
    }
}

方法二:使用协程(Coroutine)实现灵活自动触发

协程相比InvokeRepeating更灵活,支持动态调整间隔时间,取消触发可通过StopCoroutine实现。

完整代码示例:

public class RandomBottleAppearance : MonoBehaviour
{
    public GameObject bottleOne;
    public float initialDelay = 1f;
    public float repeatInterval = 2f;
    private System.Random _ranGen;
    private Coroutine _autoTriggerCoroutine;

    void Awake()
    {
        _ranGen = new System.Random();
    }

    void Start()
    {
        // 启动协程
        _autoTriggerCoroutine = StartCoroutine(AutoTriggerCoroutine());
    }

    private IEnumerator AutoTriggerCoroutine()
    {
        // 首次触发前的延迟
        yield return new WaitForSeconds(initialDelay);
        
        while (true)
        {
            RandomInvoke();
            // 等待指定间隔后再次执行
            yield return new WaitForSeconds(repeatInterval);
        }
    }

    private int RandomCounter()
    {
        int ranNum = _ranGen.Next(1, 20);
        Debug.Log($"随机数生成:{ranNum}");
        return ranNum;
    }

    private void RandomInvoke()
    {
        bottleOne.SetActive(RandomCounter() == 4);
    }

    // 取消自动触发
    public void StopAutoTrigger()
    {
        if (_autoTriggerCoroutine != null)
        {
            StopCoroutine(_autoTriggerCoroutine);
            _autoTriggerCoroutine = null;
        }
    }
}

关键说明

  • 两种方案均无需手动按键,启动后自动重复执行RandomInvoke,直到调用取消方法。
  • 可在Inspector面板调整initialDelay和repeatInterval参数,灵活控制触发时机和频率。
  • 原代码中if (bottleOne.activeSelf == true || bottleOne.activeSelf == false)属于完全冗余的判断,直接移除即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:36:10