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
相关产品推荐
相关产品推荐

