关于editor:Addressable热更新资源类型的疑问

48次阅读

共计 5424 个字符,预计需要花费 14 分钟才能阅读完成。

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(原群已满员)

正文完
 0