我有一个GameObject,当其他有效的GameObject通过碰撞触发器时,它会在List中添加和删除它们。在某些情况下,它会随机选择List中的一个对象,并用另一个GameObject替换它。它在大多数情况下工作正常,但偶尔会给予ArgumentOutOfRangeException错误。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BubbleScriptNecroGrab : MonoBehaviour
{
[SerializeField] public List<GameObject> bubbleOnes = new List<GameObject>();
[SerializeField] public List<GameObject> necroAcolytes = new List<GameObject>();
[SerializeField] GameObject activeBubble;
[SerializeField] GameObject necroAcolyte;
bool necroReady = true;
void Update()
{
if (bubbleOnes.Count > 0 && necroReady == true)
{
StartCoroutine(bubbleSignal());
}
}
// These two functions add and remove eligible bubbles from its associated list
// as they pass through the collider.
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Bubble1")
{
GameObject other = collision.gameObject;
bubbleOnes.Add(other);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if(collision.gameObject.tag == "Bubble1")
{
GameObject other = collision.gameObject;
bubbleOnes.Remove(other);
}
}
// When this is called, select a random bubble from the list, delete it and
// replace it with a prefab.
IEnumerator bubbleSignal()
{
necroReady = false;
yield return new WaitForSeconds(Random.Range(0.1f, 1.5f));
int randomList = Random.Range(0, bubbleOnes.Count -1); // adding -1 reduced amount of errors
Vector3 targetBubblePos = bubbleOnes[randomList].transform.position; // Code seems to break on this line
Destroy(bubbleOnes[randomList]);
GameObject necroAcolyteClone = Instantiate(necroAcolyte, targetBubblePos, Quaternion.identity);
necroAcolyteClone.GetComponent<AcolyteScript>().activeTarget = transform.parent.gameObject;
necroReady = true;
}
}
我怀疑的是,当bubbleSignal函数运行时,它选择了一个很大或最大的值,就像它从列表中漂移出碰撞器一样。我该如何修复这个问题?
1条答案
按热度按时间46qrfjad1#
一般情况下
-1
在并不像你想的那样。
上限已经是互斥的,因此这将永远不会返回最后一个索引。
除此之外,我在你的代码中没有看到任何明显的错误(在这一点上),这将导致我假设
bubbleOnes
是空,因此randomList = 0
,但由于根本没有元素,bubbleOnes[randomList]
已经抛出了异常。例如,当
OnTriggerExit2D
被调用时,在bubbleSignal
例程或更准确地说,在WaitForSeconds
例程完成之前,列表中只有一个元素。在这种情况下,您将从列表中删除最后一个元素,留下一个空列表,然后WaitForSeconds
将最终完成,并到达带有空列表的异常行。你应该处理这种情况,并做。
一般来说,在你的用例中,我不会在
Update
中使用协程和轮询检查来决定是否运行它。通过这种方式,您可以确保不存在计时问题,因为所有代码只有在列表在该时刻不为空时才实际执行。