Unity基础测试(1)-模型

个人测试记录项目,又琐碎又长.....

目录

 

一、疑问

二、模型文件格式

三、模型加载测试:

四、模型设置

五、Prefab/Scene文件内容

Prefab文件

Scene文件:

六、打包测试

打包文件说明:

七、基本项目打包测试:

0:项目中没有模型,场景中没有模型,纯粹的空项目

1:项目中有模型,场景中没有模型

0_1:项目中没有模型,场景中添加基本模型

0_1_1:在0_1基础上创建场景2

0_1_2:复制2,增加3、4场景,

0_1_3:减少3、4场景中的模型

0_1_4:再添加一个空场景 5

0_1_5:将主场景内的东西移动到另一个场景中 1

0_1_6:将摄像头和灯光留在启动主场景中

0_1_7:将灯光移动到场景1

0_1_8:将灯光移动到场景5

0_1_9:主场景也添加一个灯光

0_1_10:将场景1、2、3、4里面的模型部分创建预设

0_1_11:添加一个空的resources文件夹

0_1_12:将预设文件放到Resources文件夹中

0_1_13:项目中的其他场景不包括在打包的内容中

八、场景加载替换测试:

0_2:基准打包程序、能够运行中加载其他场景

0_2_1:修改场景1,添加Cube

0_2_2:添加一个fbx的模型

0_2_3:添加材质、设置材质、上颜色

0_2_4:增加贴图

0_2_5:材质参数(颜色等)修改

0_2_6:项目添加脚本

0_2_7:脚本代码修改

0_2_8:场景添加脚本

0_2_9:场景中脚本参数修改

0_2_10:场景中脚本参数修改

0_2_11:Shader添加项目中

0_2_12:Shader的Material添加项目中

0_2_13:Material添加到场景中

0_2_14:Shader代码修改

0_2_15:场景2中也加上fbx1模型

0_2_16:场景3中加上fbx2模型

0_2_17:场景4中加上fbx2模型

0_2_18:修改模型预设的内容,场景不变

九、模型加载打包测试:

1:基准打包,项目组有模型,场景中没有模型

1_0_1:添加RuntimeProfiler功能,显示运行时的状态信息

1_0_2:去掉天空盒子

1_1:场景中添加模型fbx1.fbx

1_1_0:场景中添加模型fbx1.prefab的一部分(Cube)

1_1_1:场景中只留下fbx1.fbx中的teapot,加上性能参数界面

1_1_2:场景中保留fbx5.fbx,一个有11个茶壶的模型塌陷成的比较大的模型。

1_1_3:用fbx1中的茶壶,复制10份,留11个茶壶在场景中

1_1_4:用fbx1中的茶壶,复制1000个茶壶在场景中

1_1_5:2K个茶壶

1_1_6:fbx1作成预设,并留在场景中

1_1_7:fbx1里面的teapot做出预设,并留在场景中。

1_1_8:代码引用了模型预设fbx1。

1_1_9:代码引用了模型预设teapot。

1_1_10:fbx1.fbx放到Resources里面

1_1_11:fbx1.prefab放到Resources里面

1_1_12:teaport.prefab放到Resources里面

1_1_13:fbx1.fbx放到Scene2里面,没有在Resources里面

1_1_14:read/write=true

1_1_15:模型压缩 High

1_1_16:模型压缩 Medium

1_1_17:模型压缩Low

十、模型加载速度测试

1.在Scene中

2.从项目文件中实例化

3.从预设中实例化

4.从Resource中实例化

5.从其他Scene中加载

6.从AssetBundle实例化

7.从网络实(本地)例化

8.从网络实(远程)例化


一、疑问

Unity中模型到底是什么?

    Mesh+Material(Shader+Texture)?:https://docs.unity3d.com/Manual/class-Mesh.html

外部导入的模型的文件格式可以是obj/fbx/3ds等格式。

能否自己保存模型格式?

预设文件又是什么?

Scene文件是什么?

打包后模型是已怎样的方式存在的?

运行过程中,内存中的模型是怎样的?

由什么方式能够高效的保存模型信息,像是正方形,其实可以用一个中心和边的长度来标识,一个圆形,可以用一个圆心和一个半径表示。

obj/fbx/3ds等格式是如何保存模型信息的?

Resource/Prefab/Scene/AssetBundle中的模型又是怎样的?对打包后的模型的影响。

 

二、模型文件格式

我们公司用3dmax建模,以前导入unity用3ds/obj,现在都用fbx了。

Unity支持的文件格式:https://docs.unity3d.com/cn/2020.1/Manual/3D-formats.html

Unity 支持从两种不同类型的文件导入网格和动画:

导出的 3D 文件格式,如 .fbx 或 .obj。您可以使用通用格式从 3D 建模软件导出文件,此类格式的文件可以由各种不同的软件导入和编辑。
Unity 可读取 .fbx、.dae (Collada)、.3ds、.dxf 和 .obj 文件

专有的 3D 或 DCC(数字内容创作)应用程序文件,例如来自 Autodesk® 3ds Max® 或 Blender 的 .max 和 .blend 文件格式。只能在创建专有文件的软件中编辑这些文件。专有文件通常无法在未经转换和导入的情况下直接由其他软件编辑。

注意:除非在计算机上安装了相应的 3D 建模软件,否则保存为 .ma、.mb、.max、.c4d 或 .blend 文件的资源将无法导入。这意味着,处理 Unity 项目的每个人都必须安装正确的软件。例如,如果您使用 Autodesk® Maya LT™ 许可证来创建 ExampleModel.mb 并将其复制到项目中,那么任何打开该项目的用户也需要在他们的计算机上安装 Autodesk® Maya LT™。

 

三维文件格式知多少| abc、glTF、fbx、obj、dae、stl、3ds

才知道3ds格式都快被淘汰了,fbx是autodesk家族的格式,

abc,gITF,dae以前都没接触过。

gITF说是要成为三维界的jpeg,但是3dmax导出需要插件,unity导入也需要插件,你这个怎么算呢?

Unity导入glTF格式模型:https://blog.csdn.net/beihuanlihe130/article/details/94544255

常见建模软件导出glTF:https://www.yuque.com/kivicube/manual/3d-gltf-export

从官方文档来看,unity似乎推荐fbx或者obj格式,相当于由动画的模型用fbx,没有动画的用obj吧。

警告:建议导出 FBX,而不是直接保存为项目应用中的默认格式。建议不要在生产中直接使用原生文件格式。

---------------------------------

三、模型加载测试:

fbx:正常,Convert Units不去掉模型很小;旋转轴不一致,模型带有(-90,0,0)的角度;导出时使用y轴向上或者z轴向上都一样。

obj:正常,把3dmax里面的编辑颜色也带出来了。

3ds:正常

dae:正常,旋转轴不一致,模型带有(-90,0,0)的角度

dxf:模型没有内容

abc:不识别模型

材质、贴图、动画、平滑组就不做比较了。

这么看来,还是obj好。

. obj 格式, 静态多边形模型 - 附带 UV 信息及材质路径!不包含动画、材质特性、贴图路径、动力学、粒子等信息。主要支持多边形(Polygons)模型。是最受欢迎的格式。

fbx格式:一个茶壶100k,10个1M,100个10M,1000个1000M

一个茶壶在3dmax中:4096个三角形

在Unity中:

---------------------------------------------------

四、模型设置

https://docs.unity3d.com/cn/2020.1/Manual/class-FBXImporter.html

https://docs.unity3d.com/cn/2020.1/Manual/FBXImporter-Model.html

五、Prefab/Scene文件内容

Prefab文件

里面存的是预制内的所有组件的内容,也就是说组件越多,文件越大。

里面的Transform的基本信息是明文存在的,Mesh信息是用FileID和guid标识的,基本模型的Mesh我怀疑是基本的一个资源,默认已经保存在项目中的某一处了,这里引用就行了。

这个文件最开始的部分说明它是用 YAML格式的,YAML详解 是什么:https://blog.csdn.net/lilun517735159/article/details/79230732

Scene文件:

预设在场景中用PrefabInstance表示

六、打包测试

用mono打包:

打包文件说明:

参考:https://github.com/imadr/Unity-game-hacking

│   *.exe
└───*_Data
    │   globalgamemanagers
    │   globalgamemanagers.assets
    │   level0
    │   level0.resS
        ...
    |   levelN
    |   levelN.resS
    │   sharedassets0.assets
    │   sharedassets0.assets.resS
        ...
    |   sharedassetsN.assets
    |   sharedassetsN.assets.resS
    |   resources.assets
    ├───Managed
    │       Assembly-CSharp.dll
    │       Assembly-UnityScript.dll
    │       Mono.Security.dll
    │       mscorlib.dll
    │       System.Core.dll
    │       System.dll
    │       UnityEngine.dll
    │       UnityEngine.dll.mdb
    │       UnityEngine.Networking.dll
    │       UnityEngine.UI.dll
    ├───Mono
    │   │   mono.dll
    │   └───etc
    │       └───mono
    │           │   browscap.ini
    │           │   config
    │           ├───1.0
    │           │       DefaultWsdlHelpGenerator.aspx
    │           │       machine.config
    │           ├───2.0
    │           │   │   DefaultWsdlHelpGenerator.aspx
    │           │   │   machine.config
    │           │   │   settings.map
    │           │   │   web.config
    │           │   └───Browsers
    │           │           Compat.browser
    │           └───mconfig
    │                   config.xml
    └───Resources
            unity default resources
            unity_builtin_extra

参考2:https://www.programmersought.com/article/23411832588/

参考3:https://docs.unity3d.com/ScriptReference/Build.Reporting.CommonRoles.html

七、基本项目打包测试:

0:项目中没有模型,场景中没有模型,纯粹的空项目

1:项目中有模型,场景中没有模型

0和1的打包后的结果是一样的

Textures               128.2 kb	 0.9% 
Meshes                 0.0 kb	 0.0% 
Animations             0.0 kb	 0.0% 
Sounds                 0.0 kb	 0.0% 
Shaders                7.4 kb	 0.1% 
Other Assets           0.7 kb	 0.0% 
Levels                 5.3 kb	 0.0% 
Scripts                737.4 kb	 5.0% 
Included DLLs          13.4 mb	 93.9% 
File headers           14.3 kb	 0.1% 
Total User Assets      14.3 mb	 100.0% 
Complete build size    52.3 mb

 

用CompareTo比较发现只有\Data\globalgamemanagers有一点点差异。

0_1:项目中没有模型,场景中添加基本模型

0_1_1:在0_1基础上创建场景2

场景2是从场景1复制并删除灯光和摄像头的,场景2仅仅是存在,运行后不加载

和0_1比较,多了level1和sharedassets1.asserts,少了shareassert0.assets.resS(为什么呢?)

0_1_2:复制2,增加3、4场景,

和0_1_1比较:

0_1_3:减少3、4场景中的模型

0_1_4:再添加一个空场景 5

空场景的大小是4516

0_1_5:将主场景内的东西移动到另一个场景中 1

场景的文件名称LevelN是由在Build界面中的顺序决定的

0_1_6:将摄像头和灯光留在启动主场景中

这里level1和level2的大小相同了,但是为什么sharedassets1比shareasserts2大很多呢?

0_1_7:将灯光移动到场景1

好像.resS中保存了灯光的信息,灯光在哪个场景,它就在哪

0_1_8:将灯光移动到场景5

确定了,灯光信息保存在resS中

0_1_9:主场景也添加一个灯光

奇怪了,这说明什么?

0_1_10:将场景1、2、3、4里面的模型部分创建预设

预设内的模型越多,预设文件越大

Level文件大小不变,内容变化了

0_1_11:添加一个空的resources文件夹

globalgamemanagers文件变化

0_1_12:将预设文件放到Resources文件夹中

resources.asserts出现了。

sharedassets1.assets文件小很多了,感觉像是移动到resources.asserts里面了,看了一下内容好像还真是。

这部分内容一开始在sharedassets1.assets文件里面,现在在resources.asserts里面了。

0_1_13:项目中的其他场景不包括在打包的内容中

打包后其他Level都不见了

八、场景加载替换测试:

测试打包的文件levelN能否被替换,能替换的话,通过这种方式就能替换场景了,某种程度上。

先做一个加载场景的代码和界面

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class LoadScene : MonoBehaviour
{
    public InputField sceneNameInput;

    public Toggle IsAsyncToggle;

    public Text ResultText;

    public string sceneName;

    Stack<Scene> scenes = new Stack<Scene>();

    public void LoadClick()
    {
        sceneName = sceneNameInput.text;
        if (IsAsyncToggle.isOn)
        {
            StartCoroutine(LoadAsync(sceneName));
        }
        else
        {
            Load(sceneName);
        }
    }


    public void UnloadClick()
    {
        StartCoroutine(UnloadAsync());
    }

    public void ShowLog(string txt)
    {
        ResultText.text = txt;
    }

    public void Load(string sname)
    {
        try
        {
            float start = Time.time;
            Debug.Log(sname);
            SceneManager.LoadScene(sname, LoadSceneMode.Additive);
            float usedTime = Time.time - start;
            ShowLog("Load:" + sname + "|Time:" + usedTime);
        }
        catch (System.Exception ex)
        {
            ShowLog(ex.ToString());
        }
        
    }

    public IEnumerator LoadAsync(string sname)
    {
        float start = Time.time;
        Debug.Log(sname);
        AsyncOperation op=SceneManager.LoadSceneAsync(sname, LoadSceneMode.Additive);
        while (op.isDone == false)
        {
            Debug.Log("progress:" + op.progress);
            yield return null;
        }
        float usedTime = Time.time - start;
        Scene scene = SceneManager.GetSceneByName(sname);
        scenes.Push(scene);
        ShowLog("LoadAsync:" + sname + "|Time:" + usedTime);
    }
    public IEnumerator UnloadAsync()
    {
        float start = Time.time;
        //Scene scene = SceneManager.GetSceneByName(sname);
        if (scenes.Count>0)
        {
            Scene scene = scenes.Pop();
            AsyncOperation op = SceneManager.UnloadSceneAsync(scene);
            while (op.isDone == false)
            {
                Debug.Log("progress:" + op.progress);
                yield return null;
            }
            float usedTime = Time.time - start;
            ShowLog("UnloadAsync:" + scene.name + "|Time:" + usedTime);
        }
        else
        {
            ShowLog("scenes.Count ==0");
        }
    }

}

0_2:基准打包程序、能够运行中加载其他场景

0_2_1:修改场景1,添加Cube

比较:

如果我把差异的两个文件都替换过来,老的打包也就变成了新的打包了。那应该是可以的。

但是如果只替换了level1会怎样?

测试结果是,也是可以的。可以再老的包里面加载新的模型了。

这个测试是用来确认,能够通过scene的方式存储,替换场景中的模型。假如通过Scene加载模型的方式是最快的话。

刚刚的是简单Cube,如果是fbx模型呢?老的项目中本来没有的fbx模型。

0_2_2:添加一个fbx的模型

level1修改了,sharedassets1.asserts修改了,增加了一个sharedassets1.asserts.resS了。

把这三个替换过去,可以加载fbx模型。

0_2_3:添加材质、设置材质、上颜色

和0_2_2比较:

sharedassets1.asserts和level1都复制,可以。

只复制sharedassets1.asserts则会崩溃。

只复制level1,则fbx模型消失。

0_2_4:增加贴图

只复制sharedassets1.asserts.resS:不知道什么情况

再复制sharedassets1.asserts:崩溃

再复制level1:好了。

只复制level1:有贴图的模型没有显示

0_2_5:材质参数(颜色等)修改

Material是存在sharedassets1.asserts里面?

Texture是存在.resS里面?

0_2_6:项目添加脚本

添加一个模型旋转的脚本

public class RotateSelf : MonoBehaviour
{
    public Vector3 Speed = new Vector3(0, 0, 0);

    public Transform t;
    void Start()
    {
        t = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        t.Rotate(Speed, Space.Self);
    }
}

和0_2_5比较:

C#代码编译为dll

globalgamemanagers.asserts保存类列表吗?

0_2_7:脚本代码修改

 

0_2_8:场景添加脚本

和0_2_7比较

只复制sharedassets1.asserts:没有效果

只复制level1:可以

2个都复制:可以

和0_2比较

需要复制globalgamemanagers外的所有文件

0_2_9:场景中脚本参数修改

level1修改了,

替换level1后,可以了。

0_2_10:场景中脚本参数修改

和0_2_9比较

0_2_11:Shader添加项目中

应该和前面的0_2_3之前测试的,那时有点急了,一次多步。

0_2_12:Shader的Material添加项目中

0_2_13:Material添加到场景中

复制sharedassets1.asserts就行

0_2_14:Shader代码修改

复制sharedassets1.asserts就行

0_2_15:场景2中也加上fbx1模型

这个应该接在0_2_2后面的

0_2_16:场景3中加上fbx2模型

0_2_17:场景4中加上fbx2模型

感觉像是fbx模型第一次放到哪个场景中,则存储在哪个场景的shadredasserts.asserts里面

0_2_18:修改模型预设的内容,场景不变

预设的内容是保存在level中吗?

总结:预设、材质参数、脚本参数保存在level中,材质、模型保存在shadredasserts.asserts中,贴图保存在shadredasserts.asserts.resS中

大概这样。

九、模型加载打包测试:

测试内容:内存占用、加载速度、加载流畅度

测试项:

1:基准打包,项目组有模型,场景中没有模型

添加脚本,程序运行过程中,应该是先加载场景,再运行脚本的吧,脚本Start运行的时间是多少

 

打包前Editor:

打包后

1_0:去掉启动页面后:

内存情况:刚启动38.5MB,慢慢增加,大概30s后稳定在45MB左右

第2列是CPU,第3列是GPU,这台电脑是家里的小米笔记本(GeForceMX150)。

后来测试过程中,发现有时候GPU100%了,原本最初这个测试7%左右的,现在大部分25%了。另外现在电池快没电了。

本来从7%变成25%以为是Update中更新时间信息代码导致的,结果去掉后发现不是。

多次打开相同的程序,GPU使用率会被分散,如4个时是25%左右,6个时是15%左右了。

1_0_1:添加RuntimeProfiler功能,显示运行时的状态信息

参考:https://resources.unity.com/unitenow/onlinesessions/capturing-profiler-stats-at-runtime

Editor和Builded后的参数,*是不支持的参数。

1_0_2:去掉天空盒子

1_1:场景中添加模型fbx1.fbx

1_1_0:场景中添加模型fbx1.prefab的一部分(Cube)

虽然内存还是增加到36MB了,但是从打包信息来看,虽然和上面的打包fbx1.FBX都有,但是这个fbx1.FBX应该只有Cube打包进来了。

------------

本来想用Profiler.GetRuntimeMemorySizeLong获取一个模型的内存占用情况,结果发现无论多大的模型(GameObject占用都是28KB)

然后用3dmax把1000个茶壶塌陷为一个,导入模型,结果导入了25分钟都没结束。之前没有塌陷的模型导入很快的。干嘛了?

100个茶壶塌陷的导入挺快的。

1_1_1:场景中只留下fbx1.fbx中的teapot,加上性能参数界面

Editor

打包后

Editor中,teapot的内存是266kb,打包后运行是78kb,打包中的fbx1.fbx是78.4kb,也就是打包是是多少,运行后内存大概也是多少。

 

1_1_2:场景中保留fbx5.fbx,一个有11个茶壶的模型塌陷成的比较大的模型。

Editor

Runtime

2.84MB->857.23KB,打包中是857.7KB

266*11/1024=2.857MB,78*11=858,78.4*11=862.4

1_1_3:用fbx1中的茶壶,复制10份,留11个茶壶在场景中

1_1_4:用fbx1中的茶壶,复制1000个茶壶在场景中

这是的MainThread已经是60ms左右了,那fps=1000/60=20了。

从资源管理器来看,占有内存是有所提高,不明显,56.3MB->58.8MB。

性能参数里面的Total Memory从144.71MB/36.6MB->146.24MB/40.11MB,提升不明显。

总之结论是,相同模型无论拷贝多少份,实际上在打包和内存中都只是占有了一份的空间,大体上。

DrawCall会增加,但是内存不会增加,这个和《Unity游戏优化中的》3.5.2里面写的一致。

3.5.2:通常,渲染一个、十个或一百万个相同对象,消耗的内存是相同的,因为它们都引用相同的网格数据。在这种情况下,对象之间的唯一区别是每个对象的变换。

Transform是不同的,Transform、MeshRender、MeshFilter还是会占用一些空间的。

1_1_5:2K个茶壶

这里的MainThread有500ms了,那帧率就只有2了。

1k是20,2k是2。这个有意思

1_1_6:fbx1作成预设,并留在场景中

和不是预设的情况一样,1_1_0

1_1_7:fbx1里面的teapot做出预设,并留在场景中。

和不是预设的情况一样,1_1_1,

1_1_8:代码引用了模型预设fbx1。

和1_1_0的情况一样,

99.6 kb   0.2% Assets/Models/fbx/fbx1.FBX

1_1_9:代码引用了模型预设teapot。

和1_1_1的情况一样,

78.4 kb   0.1% Assets/Models/fbx/fbx1.FBX

 0.3 kb  0.0% Assets/Models/Prefabs/Teapot001.prefab

1_1_10:fbx1.fbx放到Resources里面

和1_1_0的情况一样

99.6 kb   0.2% Assets/Resources/Models/fbx1.FBX

1_1_11:fbx1.prefab放到Resources里面

和1_1_0的情况一样

98.6 kb   0.2% Assets/Models/fbx/fbx1.FBX

 1.0 kb  0.0% Assets/Resources/Models/Prefabs/fbx1.prefab

1_1_12:teaport.prefab放到Resources里面

和1_1_1的情况一样,

78.4 kb   0.1% Assets/Models/fbx/fbx1.FBX

 0.3 kb  0.0% Assets/Resources/Models/Prefabs/Teapot001.prefab

1_1_13:fbx1.fbx放到Scene2里面,没有在Resources里面

和1_1_0的情况一样

98.6 kb   0.2% Assets/Models/fbx/fbx1.FBX

 0.3 kb  0.0% Assets/Models/Prefabs/Teapot001.prefab

1_1_14:read/write=true

在1_1_2的基础上,设置fbx5的read/write=true。

 1.0 mb  2.0% Assets/Models/fbx/fbx5.FBX

857.7Kb->1MB

运行后的模型也是增加了,1.03MB,差别不大嘛?

1_1_15:模型压缩 High

 1MB->433.8 kb  0.8% Assets/Models/fbx/fbx5.FBX

44%的压缩率?

运行后占用内存不变。

1_1_16:模型压缩 Medium

514.7 kb  1.0% Assets/Models/fbx/fbx5.FBX

1_1_17:模型压缩Low

857.7 kb  1.6% Assets/Models/fbx/fbx5.FBX

哦,这么看来前面的其实就是Low了。

Off:1.03MB

Low:857.7Kb

Medium:514.7Kb

High:433.8KB

 

合并模型

 

十、模型加载速度测试

1.在Scene中

2.从项目文件中实例化

3.从预设中实例化

4.从Resource中实例化

5.从其他Scene中加载

6.从AssetBundle实例化

7.从网络实(本地)例化

8.从网络实(远程)例化

十一、物理测试

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值