1)高通芯片GPU是否有类似于HSR的功能
​2)UGUI上的RT动图会不会导致UI更新
3)UI经常迭代外观,如何尽量少改代码
4)开发过程中该使用AssetBundle包模式,还是模拟模式?


这是第279篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

GPU

Q:高通芯片GPU是否有类似于HSR功能?望解答,谢谢。

A:参考如下:
测试案例1:小米9
点击按钮添加全屏不透明的Quad,使用Standard Shader,离相机越远,RenderQueue越小。

结果:从FPS上看,到100层,帧率也都是60帧。说明小米9上确实有类似于HSR的功能,就是不透明对象不需要手动调整渲染队列从而让靠近相机的先渲染。

测试案例2:小米5X
点击按钮添加全屏不透明的Quad,使用Standard Shader,离相机越远,RenderQueue越小。

结果:从FPS上看,1层的时候43帧,2层就掉到25帧,3层掉到17帧。说明小米5X上没有类似于HSR的功能。

测试案例3:小米5X
点击按钮添加全屏不透明的Quad,使用Standard Shader,离相机越远,不调整RenderQueue。

结果:从FPS上看,1层的时候43帧,5层的时候依旧43帧。不调整RenderQueue后,因为Unity的不透明是按照由近到远绘制的,由于Early-Z的关系,导致被遮挡的物体不会进行Fragment Shader计算了,所以帧率比较稳定。

总结:对于像地形这样的大面积且Shader复杂度通常比较高的对象,还是需要调整渲染队列到比较靠后的,因为对于低端机型,并没有HSR这样的功能。所以可以通过调整地形的渲染队列靠后,从而让Early-Z对于大地形生效,从而减少地形的渲染像素。

对于高端机型,如小米9,因为其GPU硬件支持HSR功能,所以对于不透明物体来说,渲染队列没有关系。

总体来说,还是建议调整大地形的渲染队列,对低端机型有好处。

感谢小苗子@UWA问答社区提供了回答,欢迎大家转至社区交流:
【UGUI】UI经常迭代外观,如何尽量少改代码。 抛砖引玉一个方案,也可以方便程序直接访问对象,减少GameObject.Find -- UWA问答:帮助开发者找到更好的答案


UGUI

Q:在UGUI组件上使用RenderTexture动图会不会导致UI更新?

A:对于这个问题进行了简单的实验:实验设置了一个相机拍摄不停在运动两个物体,然后得到的RenderTexture赋给UGUI上的100个RawImage。在真机上运行,此时UI更新耗时几乎为0。

理论上,这些RawImage的顶点属性没有发生变化,确实不会导致UI更新。

感谢Faust@UWA问答社区提供了回答,欢迎大家转至社区交流:
【UGUI】UI经常迭代外观,如何尽量少改代码。 抛砖引玉一个方案,也可以方便程序直接访问对象,减少GameObject.Find -- UWA问答:帮助开发者找到更好的答案


UGUI

Q:问题:之前的项目是用Lua做UI开发的。一个ToLua,一个XLua。策划或美术经常要调已经做好的UI的外观,一般需要变布局或节点层级。最早,代码里访问某个节点都是用GameObject.Find找到节点,层级关系一变,就需要程序配合改,很麻烦。怎么做到调整UI,不用改代码呢?

思路:想到一个命名规范方案:程序拿到UI的Prefab绑上UI关联Lua的脚本后,把所有程序需要访问的节点,改名成rd_xxxxx,脚本控制下的子节点rd_开头的不能重复,如果有列表的子节点,上面再挂一个辅助的脚本(比如UItemHelper)。

Lua第一次加载时遍历所有节点,缓存所有rd_xxx的节点关系到脚本里(Lua里),这样,Lua代码里直接用self.rd_xxxxx就能得到对象,也不怕Prefab层级调整,也不用多次调用GameObject.Find。

规定其他人员调整UI Prefab时,不能改掉rd_xxxxx,如果需要改则要程序配合。

参考代码:ToLua项目的一个参考修改:

关联Lua脚本对象的LuaXXX.cs里(比如叫LuaMono.cs)初始化,增加:

……if (m_params.Count == 0){//lua关联对象自动收集SetRDObjectRef(luaClass, this.gameObject, true);}else{//节点整理期间的兼容(复用UI也走这里,避免反复搜集)foreach (ParamItem pi in m_params){luaClass[pi.name] = pi.value;}}
……/// <summary>/// 把节点下所有节点查一下,如果名字是"rd_"开头的则是程序需要/// </summary>/// <param name="luaClass"></param>/// <param name="go"></param>void SetRDObjectRef(LuaTable luaClass,GameObject go,bool is_root = false){if(go){if(MyExtensions.StringStartsWith(go.name,"rd_")){
#if UNITY_EDITOR//检查是否有重复if(luaClass[go.name] != null && !luaClass[go.name].Equals(null)){GameFramework.Log.Error("{0} LuaClass already have GO key:{1} {2}", LuaScript, go.name, luaClass[go.name]);}
#endifluaClass[go.name] = go;ParamItem item = new ParamItem();item.name = go.name;item.value = go;m_params.Add(item);}if(is_root || (go.GetComponent<LuaMono>() == null && go.GetComponent<UItemHelper>() == null)){//遍历所有子节点for(int i=0;i<go.transform.childCount;++i){SetRDObjectRef(luaClass, go.transform.GetChild(i).gameObject);}}}}

UItemHelper.cs

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;public class UItemHelper : MonoBehaviour
{
#if UNITY_EDITORpublic class ParamItem{public string name;public UnityEngine.Object value;}
#endifDictionary<string, GameObject> m_nodes = new Dictionary<string, GameObject>();bool init = false;
#if UNITY_EDITOR[SerializeField]protected List<ParamItem> m_params = new List<ParamItem>();
#endifvoid Awake(){Init();}public void Init(){if(!init){m_nodes.Clear();SetRDObjectRef(this.gameObject, true);init = true;}}/// <summary>/// 把节点下所有节点查一下,如果名字是"rd_"开头的则是程序需要/// </summary>/// <param name="luaClass"></param>/// <param name="go"></param>void SetRDObjectRef(GameObject go, bool is_root = false){if (go){if (MyExtensions.StringStartsWith(go.name, "rd_")){
#if UNITY_EDITOR//检查是否有重复if (m_nodes.ContainsKey(go.name)){GameFramework.Log.Error("sub item node {0} already have GO key:{1} {2}", this.name, go.name, m_nodes[go.name]);}else
#endif{m_nodes.Add(go.name, go);
#if UNITY_EDITORParamItem item = new ParamItem();item.name = go.name;item.value = go;m_params.Add(item);
#endif}}if (is_root || (go.GetComponent<LuaMono>() == null && go.GetComponent<UItemHelper>() == null)){int childCount = go.transform.childCount;Transform t = go.transform;//遍历所有子节点for (int i = 0; i < childCount; ++i){SetRDObjectRef(t.GetChild(i).gameObject);}}}}public GameObject GetNode(string name){if(m_nodes.ContainsKey(name)){return m_nodes[name];}return null;}public Image GetNodeImage(string name){if (m_nodes.ContainsKey(name)){GameObject go = m_nodes[name];if (go != null){Image img = go.GetComponent<Image>();return img;}}return null;}public Text GetNodeText(string name){if (m_nodes.ContainsKey(name)){GameObject go = m_nodes[name];if (go != null){Text txt = go.GetComponent<Text>();return txt;}}return null;}public Button GetNodeButton(string name){if (m_nodes.ContainsKey(name)){GameObject go = m_nodes[name];if (go != null){Button btn = go.GetComponent<Button>();return btn;}}return null;}// 后期添加的节点public void AddNode(GameObject go){
#if UNITY_EDITOR//检查是否有重复if (m_nodes.ContainsKey(go.name)){GameFramework.Log.Error("sub item node {0} already have GO key:{1} {2}", this.name, go.name, m_nodes[go.name]);}else
#endif{m_nodes.Add(go.name, go);
#if UNITY_EDITORParamItem item = new ParamItem();item.name = go.name;item.value = go;m_params.Add(item);
#endif}}// 删除后期添加的节点public void RemoveNode(GameObject go){
#if UNITY_EDITORif (m_nodes.ContainsKey(go.name))
#endif{m_nodes.Remove(go.name);
#if UNITY_EDITORParamItem item = new ParamItem();item.name = go.name;item.value = go;m_params.Remove(item);
#endif}}public Dictionary<string, GameObject> GetAllRdGameObject(){return m_nodes;}
}

其他:当然各个项目情况不一样,需要各自实现。不知大家项目里遇到类似问题,用的是什么方案?

比如有的方案不希望一开始初始化,可以在创建关联Lua时,设置元表,重写_index,当self.rd_XXX这样访问时,取到索引的前缀是rd_,则去判定缓存,没有则去找对应节点关联。

A1:基于路径的UI控件查找还是比较脆弱,直接使用Unity序列化引用更好,可以随意修改结构改名字不用担心丢失。

这里有一个不错的方案:UIControlBinding

感谢张迪@UWA问答社区提供了回答

A2:别用GameObject.Find方法,编辑器序列化直接绑定到Lua。和使用原生CS绑定一样。

感谢1 9 7 3-311135@UWA问答社区提供了回答

A3:把UI控件直接序列化到C#脚本上,运行时不要用Find和GetComponent,UI面板的Prefab实例化后,直接把这些对象塞到一个Lua Table里传给Lua。

感谢唐崇@UWA问答社区提供了回答,欢迎大家转至社区交流:
【UGUI】UI经常迭代外观,如何尽量少改代码。 抛砖引玉一个方案,也可以方便程序直接访问对象,减少GameObject.Find -- UWA问答:帮助开发者找到更好的答案


Asset

Q:使用AssetBundle包,能够较大程度保证资源的正确性,但一点资源的修改就要打包,比较浪费时间,特别是美术、策划同学对它比较抵制;使用模拟模式,大概只是开发效率高一些,效果错误、循环引用等问题要延后到打包后才能发现(当然有很多其他方式可以提早发现,但属于附加手段)。

最近项目中发现,即使预加载了资源,Play过程中还是会出现非常严重的卡顿(1s+),这么长时间的卡帧导致表现效果直接不对了:比如,1s从起点移动到终点的过程,直接变成闪现到终点,成了Bug。

卡顿原因查下来是:AssetDatabase.Load出来的Prefab并不会将其依赖的Texture一起加载进内存,Prefab第一次渲染的时候Texture才会加载。我们这一个很复杂的(未优化)技能特效,用了40MB+的Texture,把UploadTexture卡了。

以这样一个特殊的问题为契机,准备重新考虑下要实行的方案,希望大家能多给些建议,可以是二者的对比选择,也可以是其他更好的做法或实现。

A:把Unity项目放在高速SSD中应该能缓解不少。

之前见到一个方案是在预加载时,创建一个玩家看不到的相机,把技能特效的Animator、ParticleSystem和音频组件等都执行一下,同时调用Camere.Render,强制把各类资源都WarmUp好,这样进入游戏后基本没有IO操作,应该能大大缓解题主描述的问题。

针对一些特效是被Timeline的轨道管理的,然后Timeline本身是一个独立模块的,可以根据技能配置找到特效(技能配置关联Timeline,Timeline关联特效),然后对特效预渲染就可以了,Timeline只是逻辑流程控制器。当然如果Timeline本身卡顿,还是要预执行一遍更好。

感谢张迪@UWA问答社区提供了回答,欢迎大家转至社区交流::
【UGUI】UI经常迭代外观,如何尽量少改代码。 抛砖引玉一个方案,也可以方便程序直接访问对象,减少GameObject.Find -- UWA问答:帮助开发者找到更好的答案

20211213
更多精彩问题等你回答~

  1. Unity增量打包AssetBundle没变化的资源也会被重新打包
  2. 在模型有UV2的情况下开启Generate Lightmap UVs
  3. 如何实现AAB包的增量更新

封面图来源于网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)

高通芯片GPU是否有类似于HSR功能相关推荐

  1. 华为郭平:很愿意使用高通芯片制造手机

    9月23日消息,在华为全联接2020媒体见面会上,华为轮值董事长郭平谈到"未来是否在旗舰机使用高通芯片"问题时表示,我们注意到高通正在向美国申请向华为供货的许可证,如果美国政府允许 ...

  2. 高通芯片曾被发现一重大漏洞 影响骁龙845等30多款芯片

    [TechWeb]4月28日消息,据国外媒体报道,在智能手机处理器市场,高通占有相当大的份额,其骁龙系列处理器是不少智能手机厂商旗舰机的选择,不过产品数量多.市场份额大也面临着出现漏洞后波及面广的问题 ...

  3. 腾讯回应封杀区块链公号;红芯服务国企非因浏览器;苹果弃用高通芯片 | 极客头条...

    「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流. 快讯速知 腾 ...

  4. 小马哥----高仿三星note3 N9006主板型号A202 高通芯片刷机拆机图示

    高仿三星note3   N9006主板型号A202 v3.0 A202有两种芯片 一种是mtk6589 一种是高通芯片 注意鉴别 上图

  5. 鸿蒙系统依靠高通芯片,鸿蒙系统+高通芯片合体!iPhone再见了

    关于鸿蒙系统,相信数码爱好者已经不是很陌生了,2019年8月9日华为开发者大会上,华为消费者业务首席执行官余承东正式宣布发布自有操作系统鸿蒙 032503br7pbrzpid7nbdcy.jpg (2 ...

  6. 高通芯片刷机过程---分析理解(启动分析故障分析)

    高通芯片刷机过程---分析理解(启动分析故障分析) 参考链接:高通芯片刷机我的分析理解(启动分析故障分析)_sishibin的博客-CSDN博客_高通firehose引导文件   高通芯片手机是市面上 ...

  7. 高通芯片处理器(CPU)性能路线图资料

    高通芯片路线图资料:      智能手机路线图: http://bbs.16rd.com/thread-465389-1-1.html LTE调制解调器分类: 智能手机平台: QCT计算路线图: QR ...

  8. 安全人员去年曾发现高通芯片一重大漏洞 影响骁龙845等30多款芯片

    [TechWeb]4月28日消息,据国外媒体报道,在智能手机处理器市场,高通占有相当大的份额,其骁龙系列处理器是不少智能手机厂商旗舰机的选择,不过产品数量多.市场份额大也面临着出现漏洞后波及面广的问题 ...

  9. 高通芯片为什么输苹果_一位软件工程师解释了为什么苹果要转向自己的芯片

    高通芯片为什么输苹果 Apple's Worldwide Developer Conference, which kicked off at the end of June, brought a sl ...

最新文章

  1. 机器学习与高维信息检索 - Note 2 - 统计决策和机器学习
  2. Redis源码解析——Zipmap
  3. POJ 3126 Prime Path(筛法,双向搜索)
  4. android里的editText怎么用,Android自定义控件EditText使用详解
  5. C语言 | C语言中的输出函数:printf()
  6. pythonwhile循环怎么修改数据类型_python基础--数据类型循环
  7. python3进阶_Python3 进阶教程 2020全新版
  8. maven中ssm框架快速搭建
  9. bootstrap入门
  10. selenium+unittest自动化测试(一)---环境搭建及用例编写规则
  11. 轻量级锁_Java高级架构师-Java锁的升级策略 偏向锁 轻量级锁 重量级锁
  12. shell编程之【告警系统】
  13. 请简述GC(垃圾回收)产生的原因,并描述如何避免?
  14. 点餐小程序购物车效果实现
  15. element ui表单必填_详解element-ui设置下拉选择切换必填和非必填
  16. 中国大学moocpython笔记_中国大学MOOC —— 学习笔记(二)
  17. 智能家居Zigbee和蓝牙哪个发展潜力更大?
  18. 安装GD库 GD库安装全过程详解
  19. linux nodejs 采集器,前端工程师通过nodejs链接linux,并上传代码进行半自动化更新,省去ssh+ftp的链接工具-前端黑科技-SegmentFault思否...
  20. Camera2 开发问题记录

热门文章

  1. Mina State machine状态机讲解
  2. 泛函分析的几个空间和平行四边形法则
  3. load和onload的区别
  4. Power BI 2021日历表DAX代码
  5. 亲爱的老狼-浮动float用法解析
  6. EML中标北爱尔兰政府2.73亿澳元经济刺激方案
  7. 基于jsp的校园二手物品交易网站
  8. 直播核心圈从业者对淘宝直播12条判断
  9. 读书笔记 来自网络
  10. 信道检测手机软件 ios_如何在iOS设备上用PS4或Xbox One的手柄玩游戏?