Note
この記事はUnity2019.1.5
で検証しています。
背景
Unityで処理をコルーチンに分けることがありますよね。
コルーチンに関する説明は他の記事を参照してください。
コルーチン内で次のフレームまで待機する時に大きく
yield return new WaitForEndOfFrame()
とyield return null
とがあります。
実行順は詳しくはUnityの公式のドキュメントにもありますが
[https://docs.unity3d.com/ja/2019.1/Manual/ExecutionOrder.html]
ネットの記事では、なんとなくyield return new WaitForEndOfFrame()
が多いようだったのでそれを使ってました。
(なんとなくnullを返すのがはばかられたのもあり)
そしてコルーチン内でマウスのクリック判定をしたくなりました。
その時にハマったものを残しておきます。
通常のクリック判定
マウスのクリック判定は Input.GetMouseButtonDown(0)
を使うと思います。
通常のコルーチンを使わない書き方は以下のような感じだと思います。
public class MouseTest : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("GetMouseButtonDown");
}
}
}
これをGameObjectにアタッチして、実行し、マウスクリックするとログが出力されます。
失敗例
yield return new WaitForEndOfFrame()
を送ってみます。
public class MouseTest : MonoBehaviour
{
IEnumerator Start()
{
while (true)
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("GetMouseButtonDown");
}
yield return new WaitForEndOfFrame();
}
}
}
こちらを実行すると、どれだけクリックしてもログが出力されません。
もしやコルーチン内ではInput.GetMouseButtonDownが使えないのでは。などと思っていました..
成功例
yield return null
にすると マウスクリックのイベントが拾えることがわかりました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseTest : MonoBehaviour
{
IEnumerator Start()
{
while (true)
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("GetMouseButtonDown");
}
yield return null;
}
}
}
結論
予想ですが、Unityのライフサイクル的に
End of frame の前にマウスイベントのフラグが初期化されるのかな..
yield return null
のほうが何かと良さそうだし、
逆に yield return new WaitForEndOfFrame()
はどういう時に使うのが効果的なんだろう..