原因
由于 Unity 场景没有挂载脚本,当要在编辑器下也可以直接运行游戏时,需要给场景动态挂载脚本,那么就需要知道 Unity 第一次进入播放状态的事件。
编辑器提供了EditorApplication.playmodeStateChanged
委托事件,会在播放状态改变的时候进行回调,但是这个事件不止会回调一次,播放、暂停、结束等都会调用这个事件,而且第一次调用时,也不是真正进入播放状态的时机。
详细的调用日志,可参考文章 http://masa795.hatenablog.jp/entry/2013/04/10/100017
当按下Play按钮的时候,会先调用EditorApplication.playmodeStateChanged
进行通知播放模式要改变了,此时只有EditorApplication.isPlayingOrWillChangePlaymode
变量为True,接着会重新类的构造,此时除了EditorApplication.isPlayingOrWillChangePlaymode
,其他变量也都还是False,在接下去的EditorApplication.playmodeStateChanged
的时候,EditorApplication.isPlaying
变量才为True。
方法
那么判断第一次真正游戏播放的事件,就需要结合EditorApplication.isPlayingOrWillChangePlaymode
变量和EditorApplication.isPlaying
变量,具体代码如下:
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
[InitializeOnLoad]
public class GameLauncher
{
static bool firstPlay = false;
static GameLauncher()
{
EditorApplication.playmodeStateChanged += ChangedPlaymodeState;
}
/// <summary>
/// 会重复进入多次
/// </summary>
static void ChangedPlaymodeState()
{
if (EditorApplication.isPaused)
{
return;
}
if (!(EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode))
{
return;
}
if (firstPlay)
{
return;
}
firstPlay = true;
Scene scene = SceneManager.GetActiveScene();
if (!scene.path.StartsWith("Assets/Scenes/"))
{
return;
}
// ...... 动态挂载脚本
}
}