1)Addressable热更新资源类型的疑难
2)本地删除FBX的DefaultMaterial在Unity重启后生效
3)如何实现MeshRenderer的成果
4)UGUI动静加载Item的DrawCall问题
5)Loading.CheckConsistency [Editor Only]编辑器上的优化问题


这是第250篇UWA技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫10分钟,认真读完必有播种。

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

Addressable

Q:Addressable能够热更新Text/Xml等原始资源,不走AssetBundle吗?正在思考是否应用Addressable作为热更新计划,有一些资源不想走AssetBundle,想间接读取,不晓得Addressable是否反对?

A:Addressable目前没有间接反对Raw资源,根本都是走AssetBundle的。

一个思路就是把这些资源独自打AssetBundle,以AssetBundle为载体,逻辑上还是当成独自的Text,Binary去读取;另外一个思路就是做扩大革新。

能够看到有TextDataProvider这个Provider类,外部用“File.ReadAllText(path);”获取资源,因而其实能够去实现一下AddressableAssetGroupSchema和BuildScriptBase,做一个RawAssetSchema和BuildScriptRawAsset的扩大来打包。

感激黄程@UWA问答社区提供了答复

Editor

Q:用了Addressables零碎,打包AssetBundle有Default Material有冗余,在打包机上运行脚本把FBX的默认材质删除后变紫,然而从新关上工程后默认材质又回来了,导致冗余还在。(Unity版本2018.4.34)

删除材质的脚本:

using System;using UnityEngine;using System.Collections;using System.IO;using UnityEditor;using Object = UnityEngine.Object;class DisableMaterialImport : AssetPostprocessor {    [MenuItem("Tools/Reimport All Model")]    public static void ReimportAllModel()    {        var assetPaths = AssetDatabase.GetAllAssetPaths();        Array.Sort(assetPaths);        Debug.LogWarning(string.Format("Total assets count: {0}", assetPaths.Length));        int processedCount = 0;        foreach (string assetPath in assetPaths)        {            string normalizedAssetPath = assetPath.ToLower();            if (!normalizedAssetPath.EndsWith(".fbx") &&                !normalizedAssetPath.EndsWith(".obj") &&                !normalizedAssetPath.EndsWith(".3ds"))            {                continue;            }            var modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter;            if (modelImporter == null || modelImporter.importMaterials)            {                continue;            }            AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ImportRecursive | ImportAssetOptions.ForceUpdate);            Debug.Log(assetPath, AssetDatabase.LoadMainAssetAtPath(assetPath));            processedCount++;        }        Debug.LogWarning(string.Format("Total processed model count: {0}", processedCount));        AssetDatabase.SaveAssets();    }    private static void FixedModelImport(ModelImporter modelImporter, GameObject model)    {        //Debug.Log("FixedModelImport "+model);        var renderers = model.GetComponentsInChildren<Renderer>(true);        if (renderers == null)        {            return;        }        modelImporter.importMaterials = false;        modelImporter.importBlendShapes = false;        modelImporter.importAnimation = false;        modelImporter.isReadable = false;        modelImporter.optimizeMesh = true;        foreach (var renderer in renderers)        {            if (renderer == null)            {                continue;            }            renderer.sharedMaterials = new Material[renderer.sharedMaterials.Length];        }/*        var animator = model.GetComponent<Animator>();        if(animator!=null) Object.DestroyImmediate(animator);*/    }
A1:我这边试验过,不会变回来啊,会不会是把工程回滚了。另外这个脚本的ReimportAllModel只对自身就没有勾选Import Materials的模型无效。

感激Prin@UWA问答社区提供了答复

A2:尝试屡次,发现关掉Cache Server就好了。

感激题主唐@UWA问答社区提供了答复

Editor

Q:我有个需要就是要将关卡里的对象通过脚本间接创立,而不是间接将Prefab拖到场景中。因而我须要能象MeshRenderer那样间接在场景中显示并不便我选中与编辑的。

代码相似这样:

    public class SpawnPrefab : MonoBehaviour    {        public GameObject prefabEntity;        void Start()        {            Instantiate(prefabEntity);        }    }

MeshRenderer有上面两个个性:
1. 在Editor模式下SceneView与GameView上面同时显示;
2. 在运行模式下绘制出的对象能够在SceneView下选中。

目前我是在OnDrawGizmos函数中调用Graphics.DrawMesh,但SceneView中却无奈选中,在Update中绘制却在Editor模式下无奈显示。我感觉如同尝试的方向错了。

A:OnDrawGizmos外面绘制显然是不行的,这个函数在打包进去Runtime都不会调用。

要在SceneView中选中编辑,肯定得是场景中的某个GameObject。(用GameObject挂MeshRenderer必定能满足“SceneView编辑”和“运行时脚本创立”两个需要的。)

如果题主的需要是肯定要用Graphics的立刻渲染接口来画Mesh,并且要在Editor下显示,那么给类加一个ExecuteAlways属性就能够了,只是还不能在SceneView中选中编辑。

如果还想实现Scene窗口下编辑性能,只能给要绘制的Mesh绑定一个场景中挂了MeshRenderer的GameObject。Graphics.DrawMesh绘制物体的Transform与这个GameObject保持一致就行了。如下图,Game窗口为OnPostRender函数中用Graphics.DrawMeshNow函数绘制的成果,Scene窗口中为绑定的用来编辑调整的物体,两者的Transform是统一的:

要害代码如下:

感激Prin@UWA问答社区提供了答复

UGUI

Q:对于动静加载Item,这样是不是算是交叉了,如果有大量的Item那得多少DrawCall,我感觉我走入了误区,求解如何学习这方面,还是说理论工作中,都不去管这种?

我这里只是举了个例子,失常我的项目中元素不可能这么少,如果多,动静加载的如何合批?如果要独自写脚本来解决动静加载的Item中的元素,那可就太不合理了。例如NGUI应用过Depth来控制面板下元素的合批,我只理解UGUI是用摆放程序来管制,如果只是这样,对动静加载的太不敌对了。

A1:共享雷同材质的网格,满足其它合批条件,以相邻程序渲染即可合批,缩小DrawCall。所以合批的要害,在于对应用雷同材质的物体,管制渲染程序。

合批条件和优化计划有以下材料:
https://blog.uwa4d.com/archives/optimzation_cpu.html
https://docs.unity3d.com/Manual/DrawCallBatching.html

Unity中影响渲染程序的因素:
https://zhuanlan.zhihu.com/p/55762351

不同的资源管制渲染程序的形式不同,如MeshRenderer,能够设置材质的RenderQueue;ParticleSystem能够设置Order In Layer和Sorting Layer等。

UGUI元素的渲染程序是UGUI这个插件自身决定的,咱们要做的是了解UGUI对元素渲染的排序形式,尽可能使雷同材质的UI元素以相邻程序渲染。具体的关键点譬如:防止同一层的UI元素相互重叠,UGUI是一层一层绘制的,保障雷同材质的UI作为同一层来绘制。如题主我的项目中的Img都放在同一层,Txt都放在第二层。如果两个Img产生叠层,就会有一个Img是作为第二层来绘制的,导致Txt的绘制与Img的绘制相互交叉,就会减少DrawCall。

只有不重叠,应用雷同图集的同层元素就会主动合批的。如果是简单的界面就只能尽可能合并图集,叠层多的状况下,只有保障材质雷同的元素应用雷同图集,并以相邻程序绘制就能够合批。UGUI里的图集一多,DrawCall就没什么好方法来管制了。

感激Prin@UWA问答社区提供了答复

A2:只有Item的面积和另外一个Item的面积不重叠,那么所有的文本都算第二层,Image都算第一层,就2个DrawCall而已。如果怕被别的UI元素影响,能够让这些Item独自放在一个Canvas外面,这样就不会受到其它UI元素的影响了。

感激Xuan@UWA问答社区提供了答复

Editor

Q:Loading.CheckConsistency [Editor Only]在编辑器上比拟耗时,请问是做什么的,如何优化?

A:ReadObject实际上是在加载之后,对Object进行反序列化。一个Prefab反序列化后,会有大量的Object。IntegrateAllThreadedObjects会遍历这些Object,而Loading.CheckConsistency就是在遍历这些Object时,对数据进行一致性测验。

所谓一致性测验,就是比方,对下图Prefab的序列化文件,会查看两个红框中的fileID是否统一。

图片起源:
https://www.cnblogs.com/luguoshuai/p/12323186.html

如这篇博文所讲,如果两个fileID不统一,会有CheckConsistency的报错。

为什么只在Editor下进行一致性测验,而打包后Runtime不须要测验呢?笔者揣测是在打包的时候曾经对所有对象都测验过了,Runtime就不须要测验,也防止了测验带来的高耗时。

证据如下图,某次打包的报错堆栈外面,蕴含了CheckConsistency的步骤:

图片起源:
https://networm.me/2019/06/23/unity-has-stopped-working/

感激Prin@UWA问答社区提供了答复

封面图来源于:Pixel Sorting
https://lab.uwa4d.com/lab/5dd4587f8bab6aaf02db4018


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在UWA问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

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