一、先看看效果:
这是使用产生的 10万个Entity的Cube,帧率 也就差不多50,还不错吧
再看看10万个Entity Sphere,帧率只有可怜的6.7
我只改变了Mesh而已,相差这么大的原因,就只能在于模型的面点了,10万个Cube的面数也就2.4M, 而 10万个Sphere的面点数却有恐怖的153M,不慢才怪啊。
二、代码实现
我写了两个脚本实现这个demo,先看看我们的GameSetting
using UnityEngine;
namespace BallDemo
{
public class GameSetting : MonoBehaviour
{
//生成的球的数量
public int BallCount = 100000;
//生成的球体的位置的范围
public int BallBound = 50;
//球的材质
public Material BallMaterial;
//球的mesh
public Mesh BallMesh;
public static GameSetting Instance { get; private set; }
private void Awake()
{
Instance = this;
}
}
}
再看看另一个生成大量Entity的代码
using UnityEngine;
using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
using Unity.Mathematics;
namespace BallDemo
{
public class BallSpawn
{
private static EntityManager _entityManager;
private static EntityArchetype _entityArchetype;
//在场景加载前,先初始化 EntityManager 和 Archetype
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void BeforeSceneLoad()
{
_entityManager = World.Active.GetOrCreateManager<EntityManager>();
//先把Position 、MeshInstanceRenderer、Rotation,后面需要设置
_entityArchetype = _entityManager.CreateArchetype(typeof(Position), typeof(Rotation), typeof(MeshInstanceRenderer));
}
//在场景加载完之后,开始生成 指定数量的 Entity
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void AfterSceneLoad()
{
for (int i = 0; i < GameSetting.Instance.BallCount; i++)
{
Entity entity = _entityManager.CreateEntity(_entityArchetype);
//这是范围内的随机位置
float3 pos = new float3();
pos.x = GameSetting.Instance.BallBound * UnityEngine.Random.value;
pos.y = GameSetting.Instance.BallBound * UnityEngine.Random.value;
pos.z = GameSetting.Instance.BallBound * UnityEngine.Random.value;
_entityManager.SetComponentData(entity, new Position() { Value = pos });
//设置材质和Mesh
_entityManager.SetSharedComponentData(entity, new MeshInstanceRenderer() {
material = GameSetting.Instance.BallMaterial,
mesh = GameSetting.Instance.BallMesh
});
}
}
}
}
这里需要说下RuntimeInitializeOnLoadMethod 跟 MonoBehaviour 是没有关系的,只要脚本里的方法是静态且带有该 属性,都会被调用。
三、给Entity使用的Material都要勾选Enable GPU Instancing
来看看不勾选与勾选后的差别
结合GPU产生 一万个Entity Cube的 FPS 为 270+
不使用GPU的 产生一万个Entity Cube的FPS为40+,差距非常大啊