Unity编译回调相关问题

///    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浪费时间

///     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以回答这个问题Unity TUIO 回调是指 Unity 引擎中的 TUIO 插件在接收到 TUIO 数据后,会调用相应的回调函数进行处理。TUIO 是一种用于多点触控交互的协议,可以在 Unity 中实现多点触控功能。 ### 回答2: Unity TUIO回调是指在Unity引擎中使用TUIO协议时,当接收到TUIO数据时触发的回调函数。TUIO是一种用于多点触摸交互的协议,它可以将多个触摸点的坐标和状态信息传递给应用程序。 在Unity中,我们可以通过编写代码来处理TUIO回调。首先,我们需要导入TUIO相关的库文件或插件到Unity工程中。然后,在代码中注册一个回调函数,告诉引擎当接收到TUIO数据时要执行的操作。 在回调函数中,我们可以获取到TUIO数据中的触摸点信息,例如触摸点的坐标、状态(按下、移动、释放等)等。我们可以根据这些数据来实现不同的交互逻辑,例如拖拽、缩放、旋转等操作。 当接收到TUIO数据时,Unity引擎会自动调用注册的回调函数,并将相关的TUIO数据作为参数传递给回调函数。我们可以在回调函数中对数据进行处理,例如更新游戏对象的位置或状态。 需要注意的是,在使用Unity TUIO回调时,我们需要确保TUIO数据和回调函数的处理逻辑是一致的。例如,如果我们希望在屏幕上进行拖拽操作,那么我们需要在回调函数中实现正确的位置更新逻辑。 总之,Unity TUIO回调是一种通过注册回调函数来处理TUIO数据的机制。它可以帮助我们实现复杂的多点触摸交互操作,提供更丰富的用户体验。 ### 回答3: Unity中的TUIO回调是一种用于处理触摸屏幕输入的技术。TUIO(Tangible User Interface Object)是一种开放式的触摸输入协议,通过该协议,可以将多点触摸或手势输入信息传递给Unity游戏引擎进行处理。 在Unity中,可以使用TUIO回调来获取触摸屏幕上的输入信息,例如触摸点的位置、触摸点的状态等。通过注册TUIO回调函数,当有触摸输入时,Unity会自动调用该函数并传递相应的信息给开发者。 使用TUIO回调可以实现许多交互效果,例如在屏幕上拖动或缩放游戏对象,实现多点触摸操作等。开发者可以根据自己的需求来编写TUIO回调函数来处理不同的操作。 在编写TUIO回调函数时,可以使用Unity提供的TUIO库来简化开发过程。该库提供了一些方便的函数和类来处理TUIO输入,例如获取触摸点的位置、判断触摸点的状态等。使用这些函数和类可以更方便地处理TUIO输入,提高开发效率。 总之,Unity的TUIO回调是一种处理触摸屏幕输入的技术,通过注册回调函数和使用TUIO库,开发者可以轻松地实现各种触摸交互效果,提升游戏的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值