找回密码
 立即注册
查看: 331|回复: 12

Unity3D项目移植UWP平台踩坑经验总结

[复制链接]
发表于 2022-8-15 20:29 | 显示全部楼层 |阅读模式
1、UWP是什么平台?和PC平台有什么区别?

       Universal Windows Platform(UWP)直译过来就是通用Windows平台,它是微软基于Win10开发的一个通用平台,微软希望自己所有的设备(包括Surface,Xbox,HoloLens等)都运行于同样的系统,然后让用户像使用苹果设备一样从自己官方的商城来下载安装应用,这样可以让应用市场中心化的同时保证系统的安全,稳定,高效。所以PC可以运行UWP平台应用,但UWP应用不止可以运行于PC,打开Win10自带的WindowsStore,里面的应用就都是UWP应用。
2、为什么写这篇文章 ?

       由于一直以来微软对UWP的推广效果不佳,Surface也没有像iPad一样成为大众平板,所以这个平台始终不温不火,知道的人也很少,其实Unity早就支持了这个平台工程的导出,但还是有很多细节Unity做的并不是完全到位。由于公司的项目想要试水此平台,所以我们才选择移植。经过1个多月的时间,我们才成功把手游项目成功移植到了UWP平台,因为关于这个平台开发的资料实在是非常稀少,甚至Google都很不好搜,关于Unity导致的UWP的问题更加稀少,所以写这篇文章一方面希望可以记录一下自己遇到过的问题,另一方面也能让后面再做移植的团队有一个参考。这篇文章主要写一些通用的功能可能存在的坑,关于打包的配置可以参考我们老大写的一篇文章。
3、关于Scripting Backend配置为.Net还是il2cpp的选择

.Net:
      优势:调试方便非常非常多,支持插件多,可以直接在打出的工程里进行源码编写,修改C#代码,不用重新出包。
      劣势:需要手动替换很多UWP平台不支持的.NetFramework的API为UWP平台的API。其中包括但不限于加密,反射等一系列API,否则打包的时候就会报错Missing API。具体的可以参考Unity和微软的这两篇文档。
Windows Store Apps: Missing .NET Types on .NET Scripting Backend
Missing .NET APIs in Unity and UWP - Windows UWP applications
       这两篇文档详细解释了缺少API的原因,并示范了如何进行修复。为了提高手动修改的效率,还可以从GitHub上找有人做好的替换库,里边写好了宏,可以直接用别人的库对自己的代码进行替换。参考这个GitHub工程。把他的库拿出来修改一下就可以用。
MarkerMetro/MarkerMetro.Unity.WinLegacy
       当然,这个过程是非常耗时且艰辛的。如果选择.Net的话还需谨慎,但是如果成功了调试起来会比il2cpp爽很多。
il2cpp:
      优势:打包方便,不需要替换API
      劣势:插件支持非常少很多插件不支持或部分功能不支持(如内嵌网页等),需要自己对插件进行修改。调试及其麻烦,因为il2cpp打包后的工程源码都是被打乱后的C++源码,如果只是小改一个参数,或是断个点之类的还好,但是如果想修改逻辑分支甚至是打个log都会遇到重重障碍,往往需要重新打包工程才能验证修改。
      所以关于两个平台的选择,我的建议是比较小型且框架不支持代码热更新的工程(如休闲类游戏)使用.Net耐下心来根据我上方分享的文档和工程把游戏工程的编译搞定,成功运行后调试起来会一帆风顺。
     但是对于比较大型的工程(如MMORPG等),我还是建议使用il2cpp进行打包,因为替换API的工作量会远超你的预期,成本高昂(不要问我怎么知道的,都是泪。。)。所以我们的项目最终采用的也是il2cpp的方式。
4、Scripting Backend为il2cpp时的内嵌网页功能

       翻遍AssetsStore,你会发现,并没有支持UWP+il2cpp的内嵌网页插件,支持内嵌网页的插件也只能够使用.Net来打包。对于.Net我推荐这款插件,可以支持非常强大的内嵌网页功能。
       然后对于两种Scripting Backend,我都推荐这个插件,里面包括了大量原生API,而且写明了两端交互使用的API。我们的内嵌网页也是在这个插件的基础上修改实现的。
       我下载的是老版本,导入的时候如果因为里面有async的函数导致编译报错,把宏加上!UNITY_EDITOR就好了,我也不知道为什么作者会有这种奇怪的失误。。 这个插件里还包括了内购等功能,但是其中内嵌网页只支持.Net的Scripting Backend。所以需要我们对WebView相关的功能进行一些魔改。
       可以先看看怎么使用UWP中的WebView,然后再看源码分析为何il2cpp不支持。


       仔细阅读源码和调试后我发现,WebView的调出方法是,实例化出一个WebView对象然后把它放入_dxSwapChainPanel(可以理解为渲染游戏画面的页面)的child中。之所以不支持il2cpp的原因是作者没有在il2cpp编译的工程下拿到MainXaml中游戏_dxSwapChainPanel的方案,对于.Net可以直接改MainXaml初始化代码把_dxSwapChainPanel注册进WebView中,但是il2cpp无法这么做。所以其实只需要找到拿到_dxSwapChainPanel的办法,然后用这个方法去替代注册的流程就可以实现一样的功能了。
       后来我在Unity的论坛中找到了这个提问,官方技术支持直接给出了源码,只要把C++源码放到Plugins里面,调用一个函数就可以拿到这个_dxSwapChainPanel,再用这个流程替代原先的注册流程就可以了。
5、InputField不支持中文输入,检测不到输入法

       由于UGUI中的InputField在UWP平台中并没有被直接当做一个文本编辑框,只是在被动的接受键盘输入,并且给它自己赋值,所以根本没有响应输入法。解决方案有两种。一是直接调用OpenScreenKeyboard接口,然后把返回的键盘的值赋给InputField,这种方法简单粗暴,但是操作非常不友好,因为没有办法使用InputField的诸如光标定位的任何功能。还有一种方法是我推荐的,使用UWP原生的TextBox盖住InputField,然后在TextBox里进行操作,当TextBox失去焦点时将其销毁,并把值赋给InputField。说一下关于这个API使用的方法。
       如何调出TextBox?
       先用刚刚上面WebView中获取_dxSwapChainPanel的办法拿到这个panel。然后引入这些NameSpace。


       在点击InputField时直接实例化一个textBox,TextBox textBox = new TextBox();进行自适应配置使位置和大小刚好盖住InputField之后通过_dxSwapChainPanel.Children.Add(textBox);将他添加进_dxSwapChainPanel即可。
       例如点击InputField之前,输入框是这样子:


       点击之后变成这样:


       输入一些内容后,再把内容赋值给原先的InputField即可实现中文输入。


       关于TextBox的一些常用API:
       textBox.Margin(可以设置textBox在屏幕中的位置和大小,需要按照InputField在Canvas中的位置和大小来计算后得到值赋给这个参数)
       textBox.LostFocus(textBox失去焦点时的事件)
       textBox.TextChanged(textBox内容改变时的事件)
       textBox.FontSize(textBox的字体大小)
       通过使用TextBox的方式就可以解决中文输入的问题了。
6、WindowsStore内购

       由于审核需要,我们也接入了Windows原生的内购功能,WindowsStore的内购现在分为两个版本,新版本是从14393版本以上开始支持,接入更加方便,可以参考微软的官方文档,而旧版本需要自己对订单验证和Report进行开发,否则不能重复购买消耗品。
       在上方介绍的WindowsStoreNative插件种有对内购详细而全面的支持,参照微软官方文档直接使用即可。
       内购的一些小坑:
       1、应用必须要发布到商店上,并且是从商店上下载回来的才可以使用内购功能,不用担心过审问题,隐藏包只要你包体验证能通过是肯定能过审的,因为不会有人人工跑你的app。
        2、旧版本的内购api,购买之后需要调用 CurrentApp.ReportConsumableFulfillmentAsync来报告已经购买完成,否则将不能重复购买。
        吐槽一句,微软的内购接入虽然不难,但是测试是真的麻烦,本地测试还是不太放心,而正式测试环境必须要你上传到商店并且从商店上下载回来的包体才能真正调出内购。当初不知道要这样才能正常跑起来内购也是查了好多错误码最后才成功的。
7、一些容易踩到的小坑和可能会用到的API

       1、Windows系统设置里的缩放会作用到UWP里你手动创建的组件上
       无论是WebView还是TextBox,他们都受到Windows系统Scale的影响,而且Surface由于分辨率很高,屏幕又小,所以大部分用户用的Scale都是250%或者更高的,这就会对TextBox和WebView自己写的自适应产生影响,导致自己创建的组件位置偏移甚至是飘到屏幕外看不见,对于这种问题可以使用Windows.Graphics.Display.DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;这个字段来获得缩放的比例来参与自适应的计算。
      2、打上传包时有appx等旁加载包,却没有用于上传的appxupload包体
     这个问题需要把解决方案配置改为Master,使用Debug和Release都打不出appxupload包体文件。
     3、一些dll通不过微软审核的验证流程


        这种情况多半是调用了一些UWP平台不支持的API,要么把这个dll阉割,实在必须的话需要找到替代品或是重新编译一个新的,文章开头部分分享的那篇文章就有我们老大对tolua.dll重新基于UWP平台编译的过程。这种问题很是头疼,不到最后一步是看不出来的。
     4、上传完包体,一直显示正在验证,几个小时都没动静
       如果遇到这个问题, 这里需要把你这次提交删掉,然后重新创建一个,挂上全局VPN,然后全程用VPN上传包体,就没问题了。
     5、区分Surface还是PC
     这个使用Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Desktop"并不能区分,如果只是为了区分鼠标还是触屏操作的话可以通过Input.touchSupport这种简单粗暴的方式来判断。
      6、关于Input.touchCount
      要注意Input.touchCount这个API是不检测鼠标的,我们项目中的EasyTouch摇杆如果在PC上用鼠标操作,它就会认为没有触摸过屏幕,直接隐藏。所以项目中如果有用到的地方,可以使用别的办法来替代。
      7、路径出现问题
      如果打包后游戏中出现一些因为路径导致的问题,那么有可能你的IO库输出的路径对/的处理有BUG,我们的项目就因为这个原因导致patch失效,查了1天才查出是这里的问题。
     8、总结

       这篇文章不一定能涵盖到所有的坑和问题,但是真的是因为网上关于Unity和UWP这方面的信息太太少了,这里记录了大部分我移植过程中实际遇到网上搜不到靠自己加班一点一点摸索填上的坑。希望把这些发到网上后可以被后人搜到节省一些不必要付出的时间。如果读者对文章有任何遗问或者错误,也十分欢迎并感谢大家的提问和指正。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-8-15 20:30 | 显示全部楼层
秀,
发表于 2022-8-15 20:34 | 显示全部楼层
收藏了
发表于 2022-8-15 20:41 | 显示全部楼层
WindowsStore里面的应用就 不 都是UWP应用,而且现在越来越少了
发表于 2022-8-15 20:44 | 显示全部楼层
请问一下博主,为什么我unity发布成UWP后,一开始在unity里挂的脚本都bu起不起作用,比如写个按钮,点了没反应,报Win32Exception
发表于 2022-8-15 20:47 | 显示全部楼层
你要看你的脚本调用的api支不支持UWP平台的。很多都是不兼容的。
发表于 2022-8-15 20:55 | 显示全部楼层
就是说unity里的许多api不支持UWP平台?
发表于 2022-8-15 21:04 | 显示全部楼层
大部分的原生API是支持的,但是你要是用一些插件什么的。你就要看插件的支持平台了。一般插件都不支持,插件支持的情况下你也要看是支持.net的还是il2cpp的。
发表于 2022-8-15 21:13 | 显示全部楼层
好的,万分感谢大佬
发表于 2022-8-15 21:15 | 显示全部楼层
问一下博主,uwp有后端的支付验证吗?
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-18 17:24 , Processed in 0.103253 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表