首页>>新闻资讯>>行业新闻

优化uGUI中的SetParent的调用开销
   来源:    添加日期:2019-02-20    
概述
    当前项目是一个相似scratch那种积木式的编程工具,编辑器用Unity的uGUI完成,但是关于大型的的工程(600多个block,每个block大约有5、6个GameObject),原有的完成在加载工程时很慢,profiler中查看,发现有很大一局部时间花在了RectTransform.SetParent调用上,这几天花了点时间,优化了这局部调用。
缘由
     RectTransform.SetParent调用,会触发许多其他的调动,比方Graphic.OnBeforeTranformParentChange,由于工程比拟大,场景中有大量的GameObjects,许多SetParent调用招致了加载性能的降低。
原有的工程加载步骤为实例化一切GameObjectsLoad保管的数据恢复GameObjects之间的援用,此时会调用SetParent重新恢复父子关系由于最初序列化数据构造设计的问题,无法在实例化时晓得parent是谁,所以招致Instantiate调用时不能传入parent参数来减少不用要的开支。
处置办法
     想到的一个办法是不依赖于Transform的父子关系,而是手动计算一切的坐标,这样我们在实例化后就不需求调用SetParent,就不会有UI的开支了。为了坚持当前代码根本构造不变,即便用本地坐标的中央能够仍然指定本地坐标,引入了一个逻辑坐标系的概念(LogicTransform)。逻辑坐标系的层级构造同原来运用unity的Transform树立的层级构造,主要的区别在与我们本人计算整个层级中的坐标,而不是unity代劳。加上我们的ui不需求旋转,只触及缩放战争移,理论计算代码很简单。下面是一个GameObjects的层级,其中黑色箭头组成的逻辑层级,红色箭头组成的unity的Transform的层级。
每个LogicTransform有一个对应的Transform,两者之间满足如下关系
LogicTransform.localScale == Transform.localScaleTransform在逻辑层级中本地坐标(非localPositon),等于LogicTransform.worldPosition采用这种完成后,工程加载的时间从最初的30s降低到了15s(仍然很慢)。
     优化ReapplyDrivenPropertiesProfiler中还发现,RectTransform.reapplyDrivenProperties也很费时,查看了uGUI的源码发现,这个局部开支来源于LayoutRebuilder在该事情处置中,调用了MarkForLayoutRebuild所致。由于我们的block规划完好是手动的,所以这局部开支也能够省掉。但是LayoutRebuilder的事情处置是私有的,所幸能够经过反射将事情处置函数交流掉。交流后的逻辑如下

     这里将不需求自动layout的game objects分配到特殊的layer上防止开支。这步优化带来的提升不是很明显,大约俭省了1.5s左右的时间。
     优化SetActive调用有些元素的显现和躲藏经过SetActive来完成。由于每次调用会触发OnEnable/OnDisable,在game objects相对较多的状况下,开支也不小,所以后来运用嵌套Canvas的办法来处置。改动后,加载速度有所提升。

大量调用RectTransform.SetParent对性能有负面影响
防止不用要的SetActive,运用嵌套Canvas也能够提升局部性能
设计良好的Save数据构造应该能够处置重新SetParent带来的开支
睿格软件

服务热线

0371-56086616

13213119956(24小时)

微信客服

点击或微信扫一扫
马上联系

收起 >