unity升级版本后华为手机特效问题

最近参与的一个旧项目由5.5升级到了2020,遇到了一些问题,主要是特效的,稍微记录一下。
一、材质球丢失问题
这个很经典,就不讲了,找美术重新拖一下就行。
二、场景变暗了
这个查了下网上说是因为unity渲染大改了,在不同版本渲染会有差异,然后找美术重新渲染一个有问题的试了下,确实没问题了,所以找美术重新渲染就可以了。
三、特效变形问题
版本升级后有一部分特效变形了,在编辑器模式可以看到是特效的缩放出问题了,修复也没什么,让美术重新调一下就行,主要是花时间查为什么在5.5没问题,在2020有问题,在网上一顿查找没找到原因,后来把出问题的特效列了一下,发现出问题的特效原本的缩放都不是1,也就是说缩放不是1的特效升级到2020后会变形,估计原因也是unity底层渲染改了,里面的一些计算放式变了导致的,另外还有个小坑,升级后原先的UI裁剪失效了,原因是unity自带的shader命名变了,导致挂载了裁剪脚本的特效无法根据名字替换。
四、华为手机特效问题
写这篇东西主要就是为了记录这个问题,新打的包在华为手机跑的时候流光特效会有显示问题,主要表现为流光为锯齿状,而且时间越久特效看上去越离谱,首先反应就是精度有问题,一上网查果然如此。然后马上按文章说的通关宏增加精度和把纹理声明为高精度纹理:

#pragma fragmentoption ARB_precision_hint_nicest
sampler2D_float _CameraDepthTexture;

打包重新看,发现没效果,心想不会吧,阿sir,我看到好几篇文章里有人用这个方法解决问题了,没想到到我这不行,继续查,接着把原先声明为half精度的一些变量改为float,再试,还是不行,这下有点懵逼了,网友们的增加精度方式都试过了都不行,难道不是精度问题?后来一位群友告诉我可能是time的问题,说time越来越大会导致精度丢失,我查了下,time的问题也比较经典,时间越长特效越慢,不过我这个好像也有可能,因为时间久了那些特效显示会越来越离谱,先试试再说,改完后再看,还是没效果,更懵逼了,毫无头绪,没办法,准备下载renderdoc抓帧debug看看了。
第二天忘了因为什么原因,有个同事说打包要改的shader在xx文件夹,我他妈直接晕了,没人跟我说过,因为项目的资源是从UIproject软链过去的,所以我一直在UIproject里改。难怪没效果,这下好了,赶紧跑去那个目录改一下,这下还不搞定?然后一顿操作,打包,最后还不行。
那就只能下renderdoc来看了,在网上找了些教程学习怎么使用renderdoc后我就开始了,手机运行游戏抓帧后我发现没法像在电脑里一样单步debug,只能看数据,通过看fragshader发现数据没什么异常在这里插入图片描述
然后再看meshview,发现texcoord0看上去有点奇怪,莫非是这个原因?
在这里插入图片描述
所以我又找了一台正常的手机抓帧来看,发现正常的手机也会有这种数据,只是看上去好像没那么多,然后再继续对比,发现华为手机的glposition好像变化比较大,然后看了下shader代码position是fix精度的,难道这个也有影响吗?之前看的文章说华为手机不能用half,所以一直没改这个。因为frag的数据看上去没什么异常,mesh的数据只有这点差异比较大,那只能改下这个试试了。最后这个修改是对的,打包后就可以了。
事情还没完,打包后原先大部分有问题的特效都可以了,但挂了这个特效的模型会闪,去看了下,是因为会闪的特效混合了这个流光shader和其他shader,其他shader原先的精度也有问题,让测试弄了个超级号给我,把混合了的其他特效全部改了一下,至此特效问题就全部解决了。
因为之前的项目是自研引擎,这种问题一般有引擎部的人去看,我已经很久没研究这类问题了,所以解决了这种问题还挺开心的,顺手也算会用renderdoc debug了,之前也用过GPA抓过其他游戏,但那时不会看信息,现在的游戏特效这么炫,好像不会抓帧会显得自己不够高级。
最后,希望对遇到问题的人有帮助吧。
参考

记一个Adreno平台下GPU精度造成的问题
结合Bug,聊一下用RenderDoc进行安卓手机联调(二)
华为手机关于LOAD_TEXTURE2D的Bug
unity shader - GPU 不支持过高的精度运算导致 黑色噪点
关于Mali GPU的浮点数异常
华为手机Shader出错水面呈条纹状解决方案(深水坑)
渲染逆向工程:打造一台调试任意Android游戏的设备
renderdoc调试总结
记unity3d下shadowmap实现影子的路程

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
/** * 初始化SDK */ private static void initSDK(String appid, String appkey) { ProxySelector defaultProxySelector = ProxySelector.getDefault(); Proxy proxy = null; List<Proxy> proxyList = null; try { proxyList = defaultProxySelector.select(new URI( "http://www.google.it")); } catch (URISyntaxException e) { e.printStackTrace(); } if (proxyList != null && proxyList.size() > 0) { proxy = proxyList.get(0); Log.d(TAG, "Current Proxy Configuration: " + proxy.toString()); } AppInfo appInfo = new AppInfo(); appInfo.setAppId(appid);// 应用ID appInfo.setAppKey(appkey);// 应用Key appInfo.setCtx(ctx); /* * VersionCheckLevelNormal 版本检查失败可以继续进行游戏 VersionCheckLevelStrict * 版本检查失败则不能进入游戏 默认取值为VersionCheckLevelStrict */ appInfo.setVersionCheckStatus(AppInfo.VERSION_CHECK_LEVEL_STRICT); // 初始化SDK Commplatform.getInstance().Init(0, appInfo, new CallbackListener<Integer>() { @Override public void callback(final int paramInt, Integer paramT) { ctx.runOnUiThread(new Runnable() { @Override public void run() { Log.i(TAG, "Init paramInt = " + paramInt); // ok.setEnabled(true); LogUtil.send("初始化: " + paramInt); } }); } }); } /** * 用户登录 * */ public static void loginEx(Context context) { Bundle bundle = new Bundle(); bundle.putString("nounce", UUID.randomUUID().toString() .replace("-", "")); Commplatform.getInstance().LoginEx(context, bundle, new CallbackListener<Bundle>() { @Override public void callback(int resultCode, Bundle bundle) { if (resultCode == ErrorCode.COM_PLATFORM_SUCCESS) { // 完成参数验签 // 处理登录成功逻辑 // HomeActivity.show(ctx); // String uin= bundle.getString("uin"); LogUtil.send("登录成功 :"); // String uin= bundle.get("nounce").toString(); String uin = Commplatform.getInstance() .getLoginUin(); LogUtil.send("登录成功 uin :" + uin); UnityPlayer.UnitySendMessage("MainScript", "HuaweiLoginBack", uin); } else { // 处理登录失败逻辑 LogUtil.send("登录失败"); } } }); } /** * 充值 * */ public static int pay(String currency) { isPaying = true; Payment payment = new Payment(); ProductBean productBean = productMap.get(currency); makeSerial(); payment.setTradeNo(orderKen); payment.setProductId(productBean.getProductId()); payment.setSubject(productBean.getTitle()); payment.setDesc(productBean.getDescription()); payment.setAmount(productBean.getPrice_amount()); payment.setCurrency(productBean.getPrice_currency_code()); payment.setNote(""); payment.setNotifyURL(""); payment.setThirdAppId(id); payment.setThirdAppName("Spot Battle"); payment.setThirdAppPkgname("com.testcrecool.mi"); final String tradeNo = payment.getTradeNo(); final String productId = payment.getProductId(); // 将订单的详细信息插入数据库 PaymentTableAdapter.insert(ctx, payment); int res = Commplatform.getInstance().UniPayExt(payment, ctx, new CallbackListener<PayResult>() { @Override public void callback(final int code, final PayResult arg1) { ctx.runOnUiThread(new Runnable() { public void run() { // 回调结果,即支付过程结束 isPaying = false; LogUtil.send("回调结果,即支付过程结束 code: " + code); if (code == ErrorCode.COM_PLATFORM_SUCCESS) { // TODO Example 1 // 根据final 的 productID 或者 orderId // 去处理商品,比如查询道具,发放道具等 // TODO Example 2 // 可以根据订单号查询订单详细信息,在做订单的处理,比如查询道具,发放道具等 // 如下: Payment payment = PaymentTableAdapter .queryByOrderId(ctx, orderKen); // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, orderKen); Log.i(TAG, "COM_PLATFORM_SUCCESS"); LogUtil.send("成功"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", orderKen); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_FAILURE) { Log.i(TAG, "COM_PLATFORM_ERROR_PAY_FAILURE"); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL) { // 购买失败 // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); Log.i(TAG, "COM_PLATFORM_ERROR_PAY_CANCEL"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL) { LogUtil.send("取消购买"); // 取消购买 // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else { LogUtil.send("Purchase failed. Error code:" + code); Log.i(TAG, "COM_PLATFORM_ERROR_UNKNOWN"); } } }); } }); if (res == 0) { LogUtil.send("000"); return 0; } else { // 返回错误,即支付过程结束 isPaying = false; LogUtil.send("返回错误,即支付过程结束"); return -1; } } /** * 获取应用内商品信息 **/ public static void querySkuDetail() { Commplatform.getInstance().getSkuDetails(ctx, new CallbackListener<List<SkuDetail>>() { @Override public void callback(int errorCode, List<SkuDetail> skuDetails) { if (errorCode == ErrorCode.COM_PLATFORM_SUCCESS && skuDetails != null) { for (SkuDetail detail : skuDetails) { ProductBean prBean = new ProductBean(); prBean.setProductId(detail.productId); prBean.setPrice(detail.price); prBean.setPrice_amount(detail.price_amount); prBean.setPrice_currency_code(detail.price_currency_code); prBean.setTitle(detail.title); prBean.setDescription(detail.description); productMap.put(detail.productId, prBean); } // showText.setText(buffer.toString()); LogUtil.send("获取应用内商品信息"); } else { // showText.setText("query error"); LogUtil.send("query error"); } } }); } /** * 生成订单号 * */ private static String makeSerial() { // 生成订单号 orderKen = UUID.randomUUID().toString().replaceAll("-", ""); return orderKen; } // 同步支付订单的漏单查询接口调用 private static void checkPay(final Payment paymentSerial) { QueryPayment queryPayment = new QueryPayment(); queryPayment.setTradeNo(paymentSerial.getTradeNo()); queryPayment.setThirdAppId(paymentSerial.getThirdAppId()); final String tradeNo= queryPayment.getTradeNo(); Commplatform.getInstance().queryPayment(queryPayment, ctx, new CallbackListener<PaymentState>() { @Override public void callback(int paramInt, PaymentState paramT) { if (paramInt == ErrorCode.COM_PLATFORM_SUCCESS) { // Step2:订单查询成功 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx,tradeNo); // 订单支付成功,可以根据订单号查询订单详细信息,在做订单的处理,比如查询道具,发放道具等 // TODO… 游戏代码 LogUtil.send("漏单查询成功!!!"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", orderKen); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_UNEXIST_ORDER) { // Step2:订单不存在 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_PAY_FAILURE) { // Step2:订单支付失败 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_SERVER_RETURN_ERROR) { // Step2:服务端返回错误 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_PAY_REQUEST_SUBMITTED) { // 订单已提交 // 根据游戏自身的体验决定如何处理 // 后续还需要继续查询 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else { // 未知错误 // 根据游戏自身的体验决定如何处理 // 后续还需要继续查询 } } }); }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值