【厚积薄发】如何理解UGUI Atlas合批时的 Include in Build选项?

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

UWA 问答社区:answer.uwa4d.com

UWA QQ群:465082844(仅限技术交流)

 

UGUI

关于UGUI的合图我有如下几点疑惑:

1、UGUI的合图是在什么时候发生的?如果说合图是在Editor下合出来的大图,那么打AssetBundle的时候似乎只打了图集文件与相关的小图,并没有看到有合成的大图出现,那是不是Unity在运行时执行Late in binding时候进行了合并呢?

2、Include in Build到底是包含了什么我的理解是如果勾选了就会包含生成的大图,如果不勾就不包含,那就又回到了问题1 ,如果不勾的话,那大图是不是在运行时生成的呢?

3小图的大小会影响性能么?首先小图图源肯定是会影响包体的大小。
基于问题1与问题2 ,如果是运行时生成的大图,那么在生成大图的时候,I/O是否以字节流的形式往空白大图内进行写入合并的?如果这样,运行时生成大图的瓶颈应该是源文件的大小与格式吧?(假如图集和图源的压缩格式不一致)

A:回答如下:

1、Unity合大图的时机是根据设置来的。

如上图,可以在打包的时候合,也可以编辑器运行的时候就合。Editor中合成的大图是放在缓存目录里:LibraryAtlasCache。

2、可以参考 About “Include in Build” behaviour

https://forum.unity.com/threads/about-include-in-build-behaviour.481433

我的理解是,勾选了Include in Build后,图集资源会被打进App包体里(不是AssetBundle包)。如果图集是AssetBundle包管理的,最好不要勾选它,会造成资源双份。至于哪些资源会双份,需要实验下看看。

3、小图源文件的大小不直接影响性能,因为Unity最终只用合并的大图,小图本身不会进入发布的App或AssetBundle包中。但通常,小图的大小和Sprite的设置会影响合并后的图集,所以会对最终性能能产生间接作用。

针对Sprites Atlas在不同Sprite Packer Mode选项下打包,做了个实验,结果分享下:

1、前三个选项(Disabled和两个Legacy Sprite Packer)结果是一样的:

打出的AssetBundle包里没有任何内容,估计这种情况下散图都没有,是完全加载不到资源的。

另:发现了疑似Unity的Bug,新创建的Atlas,和已经打包过的Atlas在禁用选项下,打包的结果不同。

2、后两个结果相同:
生成AssetBundle包的时候,图集就创建了

感谢Walker@UWA问答社区提供了回答,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5b9f99a41a1e9733ee03300b

 

制作

Q:材质的Shader,或者GameObject组件的Monobehavior,在开发过程中可能会删掉一个Shader的Property或者代码的序列化参数。这些参数被删除后,材质或者GameObject Prefab文件中,该参数的序列化数据并未被删除。

比如下图中名为TestGetDependency的组件。参数 testSubject已经从代码中删除。

但是这个GameObject的Prefab文件中,testSubject记录仍然存在。

这样会导致使用类似AssetDataBase.GetDependencies之类方法获得资源依赖时,取得testSubject 引用的物体,导致打包时包入不需要的资源。用脚本扫描SerializedObject的方式是可以清除这些引用的,但是这样需要对应每一种类似情况单独写脚本(当前只想到Shader对应材质,代码文件对应Prefab),可能有遗漏或者处理不当。

所以我希望知道,有没有一个Untiy原生的清洗方法,或者业界通用脚本来处理这类序列化引用问题。

A:重新保存下就好。

比较麻烦的是材质球,需要自己分析下然后清理serializedObject。

感谢钱康来@UWA问答社区提供了回答,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bade8deafd2174f6fe94675

 

渲染

Q:如下图,在性能报告中,我们发现Camera.Render下CreateVBO的开销较高,请问这个是如何引起的?

UWA:这本质上是你的网格重建导致的,多见于非UGUI的UI重建、Textmesh的重建等等,其重建时的CPU耗时主要受你的网格重建量大小影响,如果只是一帧其实问题不大,但如果是频繁开销,则需要特别注意了。

该回答由UWA提供,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5b966858a711f261c1677e36

 

制作

Q:如图,要实现一个势力范围的效果。应该用UI实现还是要做一个这样的场景呢?现在我们的星图是3D的Prefab,我打算在上面盖一层黑色底图,根据势力范围修改底图显示亮的区域,有没有相关的插件可以使用?要实现的话应该从哪方面入手?

A:可以创建一个RenderTexture,像素点和地图一一对应,通过修改RenderTexture颜色值,在Shader中进行对应的计算,达到效果。Unity 5.4以后,可以通过向Shader中传递数组的方式实现效果。

感谢郑骁@UWA问答社区提供了回答,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5b977889a711f261c1677e39

 

内存管理

Q:不同内存的安卓与苹果机型上(1G、2G、3G、4G...),游戏内存的峰值一般最高多少能保证不闪退。

A:这里有人会持续更新ios上的内存峰值,帖子下面还有人发了一个测试峰值的工具,用过还挺好用,大家可以参考。

https://stackoverflow.com/questions/5887248/ios-app-maximum-memory-budget.

感谢dra@UWA问答社区分享了回答,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5b8e2f5f339d267d357c6eda

实现一个item列表可以通过 Unity3D 中的UGUI组件来完成,以下是一个简单的实现步骤: 1. 创建一个ScrollView对象,它会成为你的item列表的容器。 2. 在ScrollView对象下创建一个Content对象,用于放置所有的item。 3. 创建一个item的Prefab,包含你需要显示的元素。 4. 在运行,动态生成多个item对象,将它们放置在Content对象下,以此来构建item列表。 5. 根据需要,可以对item列表进行滚动、添加或删除item等操作。 具体实现可以参考以下步骤: 1. 创建ScrollView和Content对象 在场景中创建一个空对象,命名为ScrollView。将Canvas组件的Render Mode设置为Screen Space - Overlay,然后将ScrollView对象的RectTransform组件的Anchors和Pivot都设置为(0, 0)。这样,ScrollView对象的左下角就会位于屏幕左下角。在ScrollView对象下创建一个空对象,命名为Content。将Content对象的RectTransform组件的Anchors和Pivot也都设置为(0, 0),以便于它能够与ScrollView对象的位置重合。 2. 创建item的Prefab 在项目资源中创建一个新的Prefab,将你需要显示的元素放入其中。例如,可以在Prefab中添加一个Text对象,用于显示item的标题。确保这个Prefab的RectTransform组件的Anchors和Pivot都设置为(0, 0),以便于在生成item它们能够正确地布局。 3. 动态生成item对象 在脚本中,使用Instantiate()方法动态生成多个item对象,并将它们作为Content对象的子对象。例如: ```csharp public GameObject itemPrefab; public int itemCount = 20; void Start() { for (int i = 0; i < itemCount; i++) { GameObject item = Instantiate(itemPrefab, content.transform); // 设置item的位置和大小 item.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -i * item.GetComponent<RectTransform>().rect.height); } } ``` 这段代码会生成20个item对象,将它们放置在Content对象下,并设置它们的位置和大小。这里假设item的高度是固定的。 4. 对item列表进行滚动 为了让item列表能够滚动,需要将ScrollView对象下的Scrollbar组件与Content对象的RectTransform组件相绑定。在ScrollView对象下添加一个Scrollbar组件,将它的Direction设置为Vertical,并将它的Size设置为0.2(或根据需要调整)。然后将Scrollbar组件的Value属性绑定到Content对象的RectTransform组件的anchoredPosition.y属性上。这样,当拖动Scrollbar,Content对象就会相应地向上或向下滚动。 5. 添加或删除item 如果需要动态地添加或删除item,可以在脚本中使用Instantiate()和Destroy()方法来完成。例如: ```csharp public void AddItem() { GameObject item = Instantiate(itemPrefab, content.transform); // 设置新的item的位置和大小 item.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -itemCount * item.GetComponent<RectTransform>().rect.height); itemCount++; } public void RemoveItem() { if (itemCount > 0) { Destroy(content.transform.GetChild(itemCount - 1).gameObject); itemCount--; } } ``` 这样,就可以在运行动态地添加或删除item了。当添加一个新的item,只需生成一个新的GameObject,并将它放置在Content对象下;当删除一个item,只需销毁Content对象下的最后一个子对象即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值