回避由于Unity3D编辑器播放时编译脚本重加载程序集导致报错卡死等问题

Unity3D有一个叫做”live recompile”的功能,即在编辑器处于播放状态时修改脚本代码或替换托管dll等操作时,当场触发重新编译生成项目脚本assembly,并会进行重新加载操作,然而,这个功能很多时候并不能保证重加载后的代码逻辑依然能正常运行,轻则报错,重则卡死。经过博主测试发现,Unity在重加载assembly后,会清空类实例部分成员变量的值(如在Awake中new出的数组对象等),且不负责还原。最终,为了避免由于此导致的问题,采取了一种回避的手段:通过Editor脚本方式检测是否在播放状态时触发了脚本编译,是的话立即停止播放,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Cape Guy, 2015. Use at your own risk.
using UnityEngine;
using UnityEditor;
 
/// <summary>
/// This script exits play mode whenever script compilation is detected during an editor update.
/// </summary>
[InitializeOnLoad] // Make static initialiser be called as soon as the scripts are initialised in the editor (rather than just in play mode).
public class ExitPlayModeOnScriptCompile {
     
    // Static initialiser called by Unity Editor whenever scripts are loaded (editor or play mode)
    static ExitPlayModeOnScriptCompile () {
        Unused (_instance);
        _instance = new ExitPlayModeOnScriptCompile ();
    }
 
    private ExitPlayModeOnScriptCompile () {
        EditorApplication.update += OnEditorUpdate;
    }
     
    ~ExitPlayModeOnScriptCompile () {
        EditorApplication.update -= OnEditorUpdate;
        // Silence the unused variable warning with an if.
        _instance = null;
    }
     
    // Called each time the editor updates.
    private static void OnEditorUpdate () {
        if (EditorApplication.isPlaying && EditorApplication.isCompiling) {
            Debug.Log ("Exiting play mode due to script compilation.");
            EditorApplication.isPlaying = false;
        }
    }
 
    // Used to silence the 'is assigned by its value is never used' warning for _instance.
    private static void Unused<T> (T unusedVariable) {}
 
    private static ExitPlayModeOnScriptCompile _instance = null;
}

参考文章:
Can I disable live recompile? http://answers.unity3d.com/questions/286571/can-i-disable-live-recompile.html

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。