/// Unity编译回调中进行强制编译多次导致的问题
引言
目前发现Unity在一个[UnityEditor.Callbacks.DidReloadScripts]的OnScriptsReloaded方法多次调用强制编译CompilationPipeline.RequestScriptCompilation()方法会有一些问题,发现调用两次以上会造成以下几个问题:
Unity2019.4.15版本之后,会收不到[UnityEditor.Callbacks.DidReloadScripts]的OnScriptsReloaded回调。
调用BuildPipeline.BuildPlayer()会导致Unity崩溃
解决方案是保证一个[UnityEditor.Callbacks.DidReloadScripts]的OnScriptsReloaded方法最多只存在一次强制编译。使用多个[UnityEditor.Callbacks.DidReloadScripts]的OnScriptsReloaded来解决这个问题。
[UnityEditor.Callbacks.DidReloadScripts]
static void OnScriptsReloaded()
{
// 最多只能进行强制编译1次
CompilationPipeline.RequestScriptCompilation();
CompilationPipeline.compilationFinished += CompilationFinishedBuild;
}
[UnityEditor.Callbacks.DidReloadScripts]
static void OnScriptsReloaded2()
{
// ...
}
static void CompilationFinishedBuild(object obj)
{
CompilationPipeline.compilationFinished -= CompilationFinishedBuild;
// BuildPipeline.BuildPlayer() 操作在这里调用,不要在[UnityEditor.Callbacks.DidReloadScripts]下的方法里调用
}
这样就解决了强制编译的两个问题。
BuildPipeline.BuildPlayer()会导致Unity崩溃的日志最后附上:
Android Unity闪退日志
InvalidOperationException: Calling NewScene from assembly reloading callbacks are not supported.
at (wrapper managed-to-native) UnityEditor.SceneManagement.EditorSceneManager.NewScene_Injected(UnityEditor.SceneManagement.NewSceneSetup,UnityEditor.SceneManagement.NewSceneMode,UnityEngine.SceneManagement.Scene&)
at UnityEditor.SceneManagement.EditorSceneManager.NewScene (UnityEditor.SceneManagement.NewSceneSetup setup, UnityEditor.SceneManagement.NewSceneMode mode) [0x00000] in <0b17246adadb427a972e7a69d5d75658>:0
at UnityEditor.Android.AndroidBannerUtility.ImprintProductName (System.String srcPath, System.String dstPath, System.String productName) [0x00001] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.Android.PostProcessor.Tasks.BuildResources.ReplaceIconResources () [0x00311] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.Android.PostProcessor.Tasks.BuildResources.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context) [0x00031] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) [0x00078] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.Android.PostProcessAndroidPlayer.PostProcess (UnityEditor.BuildTarget target, System.String stagingAreaData, System.String stagingArea, System.String playerPackage, System.String installPath, System.String companyName, System.String productName, UnityEditor.BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.Build.Reporting.BuildReport report) [0x0037d] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.Android.AndroidBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditor.BuildProperties& outProperties) [0x00001] in <a1f17af725844a85abc5eddf380de1b6>:0
at UnityEditor.PostprocessBuildPlayer.Postprocess (UnityEditor.BuildTargetGroup targetGroup, UnityEditor.BuildTarget target, System.String installPath, System.String companyName, System.String productName, System.Int32 width, System.Int32 height, UnityEditor.BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.Build.Reporting.BuildReport report) [0x000dc] in <0b17246adadb427a972e7a69d5d75658>:0
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions, Boolean)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions)
UnityEditor.BuildPipeline:BuildPlayer(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions)
UnityEditor.BuildPipeline:BuildPlayer(EditorBuildSettingsScene[], String, BuildTarget, BuildOptions)
ProjectBuild:BuildProject(BuildTargetGroup, SinglePackageSetting) (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:929)
ProjectBuild:BuildProjectWithSinglePackageSetting(BuildTargetGroup, SinglePackageSetting) (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:871)
ProjectBuild:AndroidBuild() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:510)
ProjectBuild:Build() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:132)
ProjectBuild:OnScriptsReloadedBuild() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:1329)
(Filename: <0b17246adadb427a972e7a69d5d75658> Line: 0)
NullReferenceException: Object reference not set to an instance of an object
at UnityEngine.Experimental.Rendering.ScriptableRuntimeReflectionSystemWrapper.Internal_ScriptableRuntimeReflectionSystemWrapper_TickRealtimeProbes (System.Boolean& result) [0x00010] in <e0370043fcc849deba726e23ed44262a>:0
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions, Boolean)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions)
UnityEditor.BuildPipeline:BuildPlayer(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions)
UnityEditor.BuildPipeline:BuildPlayer(EditorBuildSettingsScene[], String, BuildTarget, BuildOptions)
ProjectBuild:BuildProject(BuildTargetGroup, SinglePackageSetting) (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:929)
ProjectBuild:BuildProjectWithSinglePackageSetting(BuildTargetGroup, SinglePackageSetting) (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:871)
ProjectBuild:AndroidBuild() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:510)
ProjectBuild:Build() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:132)
ProjectBuild:OnScriptsReloadedBuild() (at Assets\Editor\AssetBundleEditor\ProjectBuild.cs:1329)
========== OUTPUTTING STACK TRACE ==================
0x0000020620C7BEB1 (Mono JIT Code) UnityEngine.Experimental.Rendering.ScriptableRuntimeReflectionSystemWrapper:Internal_ScriptableRuntimeReflectionSystemWrapper_TickRealtimeProbes (bool&)
0x0000020620C7C0B6 (Mono JIT Code) (wrapper runtime-invoke) <Module>:runtime_invoke_void__this___intptr& (object,intptr,intptr,intptr)
0x00007FFF9A53D690 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2809] mono_jit_runtime_invoke
0x00007FFF9A4C2912 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
0x00007FFF9A4CB96F (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2968] mono_runtime_invoke
0x00007FF73153CE4E (Unity) scripting_method_invoke
0x00007FF731536B8D (Unity) ScriptingInvocation::Invoke
0x00007FF731530B75 (Unity) ScriptingInvocation::Invoke<void>
0x00007FF72E89F0C1 (Unity) Scripting::UnityEngine::Experimental::Rendering::ScriptableRuntimeReflectionSystemWrapperProxy::Internal_ScriptableRuntimeReflectionSystemWrapper_TickRealtimeProbes
0x00007FF730811774 (Unity) ScriptableRuntimeReflectionSystem::UpdateRealtimeProbes
0x00007FF730809A85 (Unity) RenderManager::RenderOffscreenCameras
0x00007FF72F36D024 (Unity) PlayerLoopController::UpdateScene
0x00007FF72F8ECF34 (Unity) EditorSceneManager::NewScene
0x00007FF72F4F1A9A (Unity) BuildPlayerData
0x00007FF72F500805 (Unity) DoBuildPlayer_Build
0x00007FF72F4EF8E2 (Unity) BuildPlayer
0x00007FF7302DAAB8 (Unity) BuildPipeline::BuildPlayerInternalNoCheck
0x00007FF7302D87BE (Unity) BuildPipeline_CUSTOM_BuildPlayerInternalNoCheck
0x00000205D79E3ED3 (Mono JIT Code) (wrapper managed-to-native) UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions,bool)
0x00000205D79E2DB3 (Mono JIT Code) UnityEditor.BuildPipeline:BuildPlayerInternal (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions)
0x00000205D79E221B (Mono JIT Code) UnityEditor.BuildPipeline:BuildPlayer (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions)
0x00000205D79E18CB (Mono JIT Code) UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
0x00000205D79E0613 (Mono JIT Code) UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.EditorBuildSettingsScene[],string,UnityEditor.BuildTarget,UnityEditor.BuildOptions)
0x00000205D5AE619B (Mono JIT Code) [D:\Ninja3\Assets\Editor\AssetBundleEditor\ProjectBuild.cs:929] ProjectBuild:BuildProject (UnityEditor.BuildTargetGroup,SinglePackageSetting)
0x00000205D5AE3193 (Mono JIT Code) [D:\Ninja3\Assets\Editor\AssetBundleEditor\ProjectBuild.cs:871] ProjectBuild:BuildProjectWithSinglePackageSetting (UnityEditor.BuildTargetGroup,SinglePackageSetting)
0x00000205D5AD0A4B (Mono JIT Code) [D:\Ninja3\Assets\Editor\AssetBundleEditor\ProjectBuild.cs:516] ProjectBuild:AndroidBuild ()
0x00000205D4E09D3B (Mono JIT Code) [D:\Ninja3\Assets\Editor\AssetBundleEditor\ProjectBuild.cs:132] ProjectBuild:Build ()
0x00000205D4D99D3B (Mono JIT Code) [D:\Ninja3\Assets\Editor\AssetBundleEditor\ProjectBuild.cs:1365] ProjectBuild:OnScriptsReloaded ()
0x00000205CD62E125 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr)
0x00007FFF9A53D690 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2809] mono_jit_runtime_invoke
0x00007FFF9A4C2912 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
0x00007FFF9A4CB96F (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2968] mono_runtime_invoke
0x00007FF73153CE4E (Unity) scripting_method_invoke
0x00007FF731536B8D (Unity) ScriptingInvocation::Invoke
0x00007FF7314E7739 (Unity) CallMethodsWithAttribute
0x00007FF72F3601E3 (Unity) MonoDomainWasReloaded
0x00007FF7315022FB (Unity) MonoManager::EndReloadAssembly
0x00007FF731508787 (Unity) MonoManager::ReloadAssembly
0x00007FF72F90C6B3 (Unity) HandleCompileStatus
0x00007FF72F90939A (Unity) CompileScriptsWait
0x00007FF72F908B45 (Unity) CompileDirtyScriptsForEditorSyncInternal
0x00007FF72F9089D1 (Unity) CompileDirtyScriptsForEditorSync
0x00007FF72F909051 (Unity) CompileScriptsForEditorSync
0x00007FF72F3614A8 (Unity) Application::ParseARGVCommands
0x00007FF72F3587AB (Unity) Application::FinishLoadingProject
0x00007FF72FCE08E3 (Unity) WinMain
0x00007FF732CE8252 (Unity) __scrt_common_main_seh
0x00007FF812617034 (KERNEL32) BaseThreadInitThunk
0x00007FF812F62651 (ntdll) RtlUserThreadStart
========== END OF STACKTRACE ===========
iOS Unity闪退日志
[00:00:00] Enlighten: Reflection Probes took 27.000441 seconds. Cancelled, so not done yet.
[00:00:00] Enlighten: LightingDataAsset took 26.969982 seconds. Cancelled, so not done yet.
Assertion failed on expression: 'GetApplication().MayUpdate()'
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions, Boolean)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions) (at /Users/bokken/buildslave/
unity/build/Editor/Mono/BuildPipeline.bindings.cs:387)
UnityEditor.BuildPipeline:BuildPlayer(String[], String, String, BuildTargetGroup, BuildTarget, BuildOptions) (at /Users/bokken/buildslave/unity/
build/Editor/Mono/BuildPipeline.bindings.cs:286)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions) (at /Users/bokken/buildslave/unity/build/Editor/Mono/BuildPipeline.bindings.cs:269)
UnityEditor.BuildPipeline:BuildPlayer(EditorBuildSettingsScene[], String, BuildTarget, BuildOptions) (at /Users/bokken/buildslave/unity/build/
Editor/Mono/BuildPipeline.bindings.cs:252)
ProjectBuild:IOSBuild() (at Assets/Editor/AssetBundleEditor/ProjectBuild.cs:607)
ProjectBuild:Build() (at Assets/Editor/AssetBundleEditor/ProjectBuild.cs:136)
ProjectBuild:OnScriptsReloaded() (at Assets/Editor/AssetBundleEditor/ProjectBuild.cs:1358)
[./Editor/Src/Application/PlayerLoopController.cpp line 187]
(Filename: /Users/bokken/buildslave/unity/build/Editor/Mono/BuildPipeline.bindings.cs Line: 387)
Obtained 21 stack frames.
#0 0x00000000000000 in (Unknown)
#1 0x000001abbd347c in mono_jit_runtime_invoke
#2 0x000001abd95f75 in do_runtime_invoke
#3 0x000001abd95ed3 in mono_runtime_invoke
#4 0x00000107f2f7f7 in scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)
#5 0x00000107f293bf in ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)
#6 0x000001048f0f8d in
Scripting::UnityEngine::Experimental::Rendering::ScriptableRuntimeReflectionSystemWrapperProxy::Internal_ScriptableRuntimeReflectionSyste
mWrapper_TickRealtimeProbes(bool*, ScriptingExceptionPtr*)
#7 0x00000107019ba7 in ScriptableRuntimeReflectionSystem::UpdateRealtimeProbes()
#8 0x00000107015bcb in RenderManager::RenderOffscreenCameras()
#9 0x00000105619190 in PlayerLoopController::UpdateScene(bool)
#10 0x00000105e83c14 in EditorSceneManager::FinishNewScene()
#11 0x00000105e83b26 in EditorSceneManager::NewScene(NewSceneParameters const&)
#12 0x0000010583b984 in BuildPlayerData(BuildTargetPlatformGroup, BuildTargetPlatform, BuildPlayerOptions, BuildCompression const&,
std::__1::vector >, std::__1::allocator > > >, AssetBundleBuildData*, std::__1::vector >&, ScriptingObjectPtr, Vector2f, BuildReporting::BuildReport&, core::basic_string > const&, BuildReporting::BuiltAssetBundleInfo*, core::basic_string >
const&)
#13 0x0000010580cb19 in DoBuildPlayer(BuildPlayerSetup const&, std::__1::vector >&, core::basic_string >, std::__1::vector >, std::__1::allocator > > >, bool,
BuildReporting::BuildReport&, BuildReporting::BuiltAssetBundleInfo*, core::basic_string > const&)
#14 0x0000010581298a in BuildPlayer(BuildPlayerSetup const&, BuildReporting::BuildReport&)
#15 0x00000106b3d207 in BuildPipeline_CUSTOM_BuildPlayerInternalNoCheck(ScriptingBackendNativeArrayPtrOpaque*,
ScriptingBackendNativeStringPtrOpaque*, ScriptingBackendNativeStringPtrOpaque*, BuildTargetPlatformGroup, BuildTargetPlatform,
BuildPlayerOptions, unsigned char)
#16 0x000001cb2b20b0 in (wrapper managed-to-native) UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck
(string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions,bool) {0x7f83e10fb2b8} + 0xc0 (0x1cb2b1ff0
0x1cb2b2162) [0x1ab7cec80 - Unity Child Domain]
#17 0x000001cb2b11eb in UnityEditor.BuildPipeline:BuildPlayerInternal
(string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions) {0x7f8436f06910} + 0x1ab (0x1cb2b1040
0x1cb2b123a) [0x1ab7cec80 - Unity Child Domain]
#18 0x000001cb2b07f3 in UnityEditor.BuildPipeline:BuildPlayer
(string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,UnityEditor.BuildOptions) {0x7f8436f067c0} + 0x373 (0x1cb2b0480
0x1cb2b0948) [0x1ab7cec80 - Unity Child Domain]
#19 0x000001cb2b00c3 in UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions) {0x7f8436f06798} + 0x193 (0x1cb2aff30
0x1cb2b0118) [0x1ab7cec80 - Unity Child Domain]
#20 0x000001cb2af07b in UnityEditor.BuildPipeline:BuildPlayer
(UnityEditor.EditorBuildSettingsScene[],string,UnityEditor.BuildTarget,UnityEditor.BuildOptions) {0x7f8436f06748} + 0x29b (0x1cb2aede0
0x1cb2af0dc) [0x1ab7cec80 - Unity Child Domain]
/ Unity强制进行编译,及编译后的回调处理
引言
在开发过程中有时会需要强制进行编译,并且在编译后要进行逻辑处理,则需要做以下操作。比如在命令行打包时,使用命令参数-quit 来回开关Unity很耗时,即可以调用一次Unity的接口。假如项目中有Lua编译环节,因为Clear Lua和Generate Lua会有c#的变动,会导致代码需要编译,则可以在Clear Lua和Generate Lua两个步骤下调用API进行强制编译,然后再回调里再进行Clear Lua或Generate Lua之后的操作。
Unity强制进行编译的API :
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
编译后的回调处理(回调主要是以下这个标签及方法,步骤从1~3):
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnScriptsReloaded()
{
if (目前在Clear Lua)
{
2. 进行Generate Lua...
// 强制编译
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
}
else if (目前在Generate Lua)
{
3. 进行Generate Lua之后的操作...
}
}
// 命令行调用的c#方法
static void DoShellBuildPatch()
{
1. 进行Clear Lua
// 强制编译
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
{
因为这样就开关1次Unity,即可完成打包流程,也不需要在打包脚本里分别调用Clear Lua和Generate Lua的接口,避免多次开关Unity浪费时间
///