Reputation: 55
I have met a strange problem when using Coroutine in Unity. Before modification, my code is as the following:
IEnumerator Destory()
{
yield return new WaitForSeconds(destoryDelay);
yield return StartCoroutine(Timer.Start(0.5f, false, gameManager.EnableBtnSummon));
GameObject.Destroy(this.gameObject);
}
Time.Start()
is an utility written by myself and used for delay invoke.
public static IEnumerator Start(float duration, bool repeat, Action callback)
{
do
{
yield return new WaitForSeconds(duration);
if (callback != null)
callback();
} while (repeat);
}
Because Time.Start()
includes WaitForSeconds()
, so I decided to modify above code as the following:
IEnumerator Destory()
{
//yield return new WaitForSeconds(destoryDelay);
yield return StartCoroutine(Timer.Start(destoryDelay+0.5f, false, gameManager.EnableBtnSummon));
GameObject.Destroy(this.gameObject);
}
Unfortunately, console throw an error:
ArgumentException: Value does not fall within the expected range.
gameManager.EnableBtnSummon
is just an Action processing game logic. After debug, i make sure that error occurred before this function run. But i will show it for more clues.
public void EnableBtnSummon()
{
//will not reach this!
print("Enable Button Summon");
//if detecting monster, change relative sprite of monster medal
if (currentMonsterIndex != -1)
{
Image captureMonsterSprite = monsterMedalList.transform.GetChild(currentMonsterIndex).GetComponent<Image>();
captureMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex];
Image gameOverMonsterSprite = gameOverMonsterList.transform.GetChild(currentMonsterIndex).GetComponent<Image>();
gameOverMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex];
currentMonsterIndex = -1;
captureMonsterCount++;
}
if (captureMonsterCount == monsterIndexDictionary.Count) return;
var summonAnimator = btnSummon.GetComponent<Animator>();
summonAnimator.SetBool("isSearch", false);
btnSummon.enabled = true;
btnExit.enabled = true;
fogParticleSystem.Play();
}
I cannot understand it, could someone tell me what happens? thx...
Upvotes: 2
Views: 32108
Reputation: 125245
The exception:
ArgumentException: Value does not fall within the expected range.
is happening on this line of code:
yield return StartCoroutine(MoveTowards.Start(destoryDelay + 0.5f, false, gameManager.EnableBtnSummon));
This has nothing to do with StartCoroutine
as the title of the question says. The source of the problem is the MoveTowards.Start
coroutine function. The third parameter(Action callback
) that is passed into it is the issue.
The issue is that you are passing null
to the third parameter of the MoveTowards.Start
function. Since you are passing gameManager.EnableBtnSummon
to that third parameter, this means that the gameManager
variable is null
.
You can verify this by adding Debug.Log(gameManager)
before that line of code. The output should be "null" in the Console tab.
FIX:
Initialize the gameManager
variable:
Name the GameObject
your GameManager
script is attached to "ManagerObj" then use the simple code below to initialize the gameManager variable.
GameManager gameManager;
void Awake()
{
gameManager = GameObject.Find("ManagerObj").GetComponent<GameManager>();
}
Note:
Rename your Start
function to something else as there is already Unity built in function named "Start" and "Awake". You need to change the name to something else but this is not the problem.
Upvotes: 12