Unity编辑器界面有三种模式:
- Play Mode: 按下Play按钮进入游戏的这种模式,Unity称之为Play Mode
- Edit Mode:正常的Unity编辑状态就是Edit Mode
- Prefab Mode:Unity进入prefab时对应的编辑状态叫Prefab Mode
Unity里继承MonoBehaviour的脚本,并不是一直都会执行的。Unity默认只有在Play Mode下,才会运行游戏当前运行场景里的GameObject挂载的脚本。
为了满足实际需求,Unity支持通过[ExecuteInEditMode]
或[ExecuteAlways]
两种参数使脚本在Play Mode以外的状态下被执行,[ExecuteEditMode]
支持脚本在Edit Mode下运行,[ExecuteAlways]
是在Unity2018.3及以后的版本新加入的功能,能够支持脚本一直运行。(ps:由于[ExecuteInEditMode]
并没有考虑Prefab Mode,严格意义上讲Prefab Mode也属于Edit Mode,所以这个功能会逐渐被Unity弃用,最后应该会被[ExecuteAlways]
所替代)
两种的写法是差不多的,只需要在对应脚本的类前加上对应代码即可,如下所示,
[ExecuteInEditMode]
public class Example1 : MonoBehaviour {
...
}
[ExecuteAlways]
public class Example2 : MonoBehaviour {
...
}
ExecuteInEditMode
值得注意的是,与PlayMode不同的是,函数并不会不停的执行。
Awake
和Start
:加载时调用,也就是脚本赋给物体的时候被调用Update
: 只有当场景中的某个物体发生变化时,才调用,当进程切出去再回来,也会调用一次。OnGUI
: 当GameView接收到一个Event时才调用。OnRenderObject
和其他的渲染回调函数 : SceneView或者GameView重绘时,比如,一直移动鼠标的时候OnRenderObject
会被调用。
使用了[ExecuteAlways]
参数的类,仍然可以在原来的Play Mode下正常运行,举个例子,如下图所示:
[ExecuteInEditMode]
public class TestA : MonoBehaviour
{
private void Awake()
{
Debug.Log(1);
}
private void Start()
{
Debug.Log(2);
}
private void Update()
{
Debug.Log(3);
}
}
在Edit Mode下,将其挂载到一个GameObject下,会打印如下消息:
运行游戏,可以看到又调用了一次Awake和Start函数:
关闭游戏,回到Edit Mode:
ExecuteAlways
ExecuteAlways
可以看作是ExecuteInEditMode
的改进版,支持Prefab Mode下的脚本调用,其余的与ExecuteInEditMode
基本完全相同,具体代码如下:
[ExecuteAlways]
public class Example : MonoBehaviour {
void Start()
{
if (Application.IsPlaying(gameObject))
{
// 若在Play Mode下
// Play logic
}
else
{
// 若在Edit Mode下
// Editor logic
}
}
}