ストーリーパートを作っていて文字を1文字ずつ表示するスクリプトを作っていたのですが、スキップしようとした時にコルーチンが止まらずセリフが悪魔合体していたバグを見つけたのでその対処方法を紹介します。
環境
Unity 2020.2.2f1 Personal
修正前のコード
private void Update()
{
if (Keyboard.current.zKey.wasPressedThisFrame)
{
StopCoroutine(NextStep());
StartCoroutine(NextStep());
}
}
private IEnumerator NextStep()
{
// コルーチン処理
}
個人的には文字列での指定よりIEnumerator型で渡す方が好きです。
特に止める必要のないコルーチンであればこれでも問題ありませんが、
残念ながらこれではコルーチンが止まらず、2つのコルーチンが実行されてしまいます。
原因はStopCoroutineの仕組みです。
IEnumerator型で開始するタイプの書き方で止めるには同一インスタンスをStop側に渡してあげる必要があります。
上の書き方ではStartとStopは別インスタンスとなってしまうため、止まらないということです。
修正後のコード
1つはStartとStopで同じインスタンスを渡してあげるよう変更します。
private IEnumerator nextStep;
private void Update()
{
if (Keyboard.current.zKey.wasPressedThisFrame)
{
StopCoroutine(nextStep);
nextStep = null;
nextStep = NextStep();
StartCoroutine(nextStep);
}
}
または文字列での指定の方法でも問題なく止まります。
その際は少しでもタイポミスを防ぐようnameofを使うことをおすすめします。
private void Update()
{
if (Keyboard.current.zKey.wasPressedThisFrame)
{
StopCoroutine(nameof(NextStep));
StartCoroutine(nameof(NextStep));
}
}