• Unity 头顶信息的优化


    在这里插入图片描述
    人物头顶上文本或者图片,都是放在一个世界空间渲染的canvas下面的。
    我喜欢使用的头顶UI的设计方式。
    请添加图片描述

    首先枚举是统一的,利用一个十六进制单位的枚举来表示所有存在的预制体类型,WorldUIType是为了除了人物头顶Top上的UI,还可以扩展采集物使用的世界UI,人物脚底光圈这种,他们都属于UI,有一定的公共逻辑(位置跟随),但也有不一样的地方,例如脚底光圈不需要广告牌效果以及无论远近保持恒定大小之类的这种效果。所以可以通过继承IWorldUI来扩展世界UI类型。
    cmd_worldUIBase
    worldSubUI具体预制体使用需要的现场数据,在mvc设计里面cmd就是model,view就是继承IWorldSubUI的类,继承cmdBase的类都有WorldUIFlags类型,需要加载的预制体路径,加载出来的prefab,受对象池控制,subui的加载现场我也同样复用的这个,接口有是否加载完成,copy和跟别的判断是否相等,在当前环境下是否允许显示等(传IWorldUI判断当时的flag现场)。WorldUIFlags,worlduitype等枚举和cmd现场都是频繁变动的东西,可以放在一个文件。
    IWorldSubUI
    内部可以保留一份cmd_worldUIBase的拷贝,当做是上一次更新之后的UI数据,不要直接使用Iworldui传过来的引用,为了方便更新subui的时候拿上一次数据跟最新的数据进行对比后更新。
    IWorldUI
    在这里插入图片描述
    可以利用partical关键字把IWorldUI分成两个文件,一个文件专门控制具体显示subui的预制体加载与标签更新显示等游戏逻辑,例如:
    1.加载父亲在这里插入图片描述
    一般来说一个角色模型都有一个这个东西,后面的跟随,广告牌都可以控制他,然后加载具体的subUI到他的孩子里面,iworldUI加载在一个统一的使用world camera的canvas父亲下面。
    2.根据标识更新subui,需要时加载,不需要时判断是否是常驻subui(例如血条,名称,当前不显示,但是之后还可能会多次利用,这种的就直接隐藏就好了,不要真的卸载),而其他的可以直接卸载。
    另外一个可以封装绑定点接口,以及一些通常会使用到的表现功能供子类组合使用,这个换个项目也可以直接搬过去。例如:
    1.位置跟随
    2.旋转达成广告牌效果(让)
    3.控制旋转取消unity特有的近大远小功能,让UI无论远近看起来都一样,利用worldUI在世界相机的坐标下 的相对距离z来*一定的系数构建一个线性关系式来控制缩放。
    float scale = 1;
    scale = mainCam.transform.InverseTransformPoint(cellViewPrefab.transform.position).z * param.UI_SCALE_ADJUST_FACT;
    var result = scale
    param.originLocalScale
    4.具体的需求设置alpha等。
    WorldUIMisc
    一些表格相关的数据处理与接口。
    WorldUIManager
    监听一堆事件,控制subui的加载与卸载,提工一个公共的LateUpdate让所有的subui在这里面lateupdate,确保lateupdate只有一个
    优化点可以有:
    1.需要加载的东西做成一个一个预制体而不是放在一起,需要型加载,这样就可以最大减少UI的数量
    暂时就想到这些。
    2.保存当前是否需要显示加载某些头顶信息状态可以用一个整数,按位取来判断。
    3.确保系统中使用的update只有一个。
    为什么一定需要保存是否加载某些头顶信息的状态?
    举个例子,当A头顶UI显示的时刻是B头顶UI不存在的时候,就需要在显示A之前判断一下是否存在B了。一般来说每次更新一次标记都会刷新当前存在的所有头顶UI,如果头顶UI的现场数据不对应的时候就需要更新。
    头顶UI根据距离相机位置控制遮挡关系的问题
    不要去调整hierarchy下的层级问题,谁后加载谁就放最下面好了,通过与摄像机之前的相对z距离去设canvas的覆盖order就行了。order 公式可以=100-z ,z是距离摄像机的距离,化除法为减法。

    是否考虑直接使用UIOverlay canvas渲染方式?

    直接使用overlay canvas渲染,这样就不用考虑 旋转和缩放问题,只需要把世界坐标转屏幕坐标更新坐标即可,如果在更新位置的时候有延迟,则需要找到可能是相机更新的时候同步更新一次位置,但是overlay角色模型不能跟剧距离挡住要头顶信息UI,我们项目中没有使用这种方式。

    使用世界相机canvas渲染如何考虑还画布像素大小和世界大小单位换算的问题在这里插入图片描述

    在这里插入图片描述
    举个例子,像这样每3个物理世界坐标的单位等于100像素,那么在这个模式下,UI在渲染宽度的时候是使用世界坐标单位来渲染的,所以我们在普通UI下拼的宽度在世界空间下看起来就会显示的很大,解决方法就是把外层UI物体的整体缩放缩小到3/100的比例,例如我下面的代码那样,同理,世界空间下z的距离也要缩小成显示在画布下的像素单位同比例下的显示。
    在这里插入图片描述
    在这里插入图片描述

    优化问题:

    1.layout使用在要更新位置的时候才启用,平时不启用
    在这里插入图片描述

    举个例子,使用自己重写的layout,update则是rebuild之后的下一帧,相当于rebuild万之后的回调,这样就可以外部使用的时候打开layout,然后rebuild,rebuild之后关闭
    2.加canvas组件
    3.委托是一个类,不要再循环中使用action之类的,会造成每帧的gc时间消耗。

  • 相关阅读:
    网络安全(黑客)自学
    react经验1:监听窗体尺寸变化
    PyCharm新手入门
    vue2和vue3浏览器兼容性对比
    滑动窗口总结模板与例题(c++)
    mysql innodb 存储引擎
    如何让电脑永不息屏?Python:这事我熟,只需5行代码...
    【vue3】组件间通讯
    六级阅读3大核心技巧-因果关系题:如何识别因果
    编译+链接和预处理
  • 原文地址:https://blog.csdn.net/Icecoldless/article/details/126709089