Unity优化

推荐阅读:

Unity 优化(一) ------ 优化前了解以及方向

FPS:画面每秒传输帧数,,要避免动作不流畅的最低是30;值越大性能越好
CPU:计算每帧需要消耗的时间,值越低说明计算越快,值越小性能越好
Batches:将某些DrawCalls合并,数量为合并后DrawCall的数量。
Tris:三角面
Verts:顶点
SetPass call:Shader中Cpu每次运行Pass之前都会产生一个SetPass call。

Unity 优化(二) ------ 资源优化

长时间音乐使用Mp3格式(使用压缩格式),例如:背景音乐等
短时间音乐使用wav格式(不使用压缩格式),例如:音效
在这里插入图片描述

减少冗余资源和重复资源
A、Resources目录下的资源不管是否被引用,都会打包进安装包
不使用的资源不要放在Resources目录下
B、不同目录下的相同资源文件,如果都被引用,那么都会打包进资源包,造成冗余
保证同一个资源文件在项目中只存放在一个目录位置
资源优化:使用UWA工具
渲染优化(GPU)和代码优化(CPU)
GPU:包括场景渲染和灯光处理等
CPU:数值计算

LOD——层级

当模型离视野近时,显示比较精细的模型,离视野比较远时显示比较粗糙的模型。
实现方法:
新建一个空物体,添加LOD Group组件,将模型拖进精细度按下图提示拖进对应位置,可根据实际情况调节每个LOD的占比。
在这里插入图片描述

遮挡剔除

目的;降低DrawCall
原理:在摄像机视野内的物体显示,在视野外的物体不显示。
实现方法:
(1)在场景中创建很多物体(方便观察)。全选中—点击Static—Occluder Static
[外链图片转存失败(img-DedDmHb2-1567147525008)(https://img.hacpai.com/file/2019/08/image-ec9a4dd6.png)]
(2)点击Windows—Occlusion Culling
image.png
image.png
(3)选择指定相机用于遮挡剔除计算
image.png

光照贴图

目的:降低Batches
实现方法:
(1)搭建好场景,选中场景中所有需要被光照的物体—点击Static—LightmapStatic
image.png
(2)点击Windowa—Lighting—Settings
image.png
(3)选择需要被烘焙的光源,将模式选择烘焙模式
image.png
(4)Scene—取消勾选—Generate Lighting
image.png
(5)选择烘焙后,下方是烘焙进度
image.png
(6)选择所有被烘焙的光源,取消Light勾选
image.png
这时还能看见光照效果,这时因为使用烘焙,生成了光照贴图
image.png
注意:如果觉得光照强度过强,在(4)前可修改
Light组件中Indensity值,值越低,光照越暗

合并Mesh

要求合并的mesh使用相同的材质。
实现方法:
(1)创建一个空物体MeshCombine,并为其创建几个子物体,子物体层级任意
image.png
(2)新建脚本并挂在到(1)中的空物体MeshCombine上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshCombine : MonoBehaviour {

	// Use this for initialization
	void Start () {
        CombineMesh();
	}
    void CombineMesh() 
    {
        MeshFilter[] filters = GetComponentsInChildren<MeshFilter>();//获取空物体下所有子物体的MeshFilter组件并保存为一个数组
        CombineInstance[] combiners = new CombineInstance[filters.Length];//unity提供的一个类,用于处理合并的实例
        //将filters的一些属性设置给combiners
        for (int i = 0; i < combiners.Length; i++) 
        {
            combiners[i].mesh = filters[i].sharedMesh;
            combiners[i].transform = filters[i].transform.localToWorldMatrix;//这里的transform不是一个组件而是一个矩阵转换,用于世界座标与局部座标之间的转换
        }
        Mesh finalMesh = new Mesh();
        finalMesh.CombineMeshes(combiners);//合并mesh
        GetComponent<MeshFilter>().sharedMesh = finalMesh;//将合并后的Mesh赋值到父物体上

    }
}

(3)为(1)中的空物体MeshCombine 添加两个组件:
MeshRender组件:负责渲染
MeshFilter组件:用于存放合并后的mesh
并未MeshRender组件选择一个需要的材质。
(4)游戏运行,会将MeshCombine下的所有子物体中的Mesh合并并赋值到MeshCombine物体上,因此场景中将会出现两个一模一样的mesh,这时在游戏运行时可直接删除其下的子物体,这时可明显看见Batches减少。

ObjectPool

对象池的使用可以说是非常常见。直接上代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour {

    public int objCount=5;//对象池中该类对象初始生成的个数
    public GameObject buttlePreb;//需要实例化的预制
    private List<GameObject> poolList = new List<GameObject>();//存放对象

	void Start () {
		InitPool();
	}
    //初始化对象池
    void InitPool()
    {
        for (int i = 0; i < objCount; i++) 
        {
            GameObject go = Instantiate(buttlePreb);//实例化对象
            poolList.Add(go);//将实例化的对象添加到对象次
            go.SetActive(false);//设置为隐藏—即未被使用
        }
    }
    //从对象池中取对象
    public GameObject ShowObj()
    {
        foreach (GameObject go in poolList)
        {
            if (!go.activeInHierarchy)
            {
                go.SetActive(true);
                return go;
            }
        }
        return null;
    }
    //使用协程,使得对象生成后等待指定时间隐藏—即放回对象池
    public IEnumerator HideObj(GameObject go)
    {
        yield return new WaitForSeconds(3);
        go.SetActive(false);
    }
}

使用对象池:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class startBuntle : MonoBehaviour {

    private ObjectPool objPool;

	void Start () {
        objPool = GetComponent<ObjectPool>();
	}
	
	void Update () {
        if (Input.GetKeyUp(KeyCode.K)) 
        {
            GameObject go = objPool.ShowObj();
            if (go != null) 
            {
                //对象次还有可用对象
                go.GetComponent<Rigidbody>().velocity = transform.forward * 30;
                StartCoroutine(objPool.HideObj(go));
            }
        }
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章