要解决性能的瓶颈问题,在DOTS中我们将不再使用Unity自带的物理组件.
下面来分享一下在DOTS中当如何使用物理插件.
一.导入插件
在使用DOTS系创建的实体我们会发现,游戏物体无法受物理系统影响进行运动.于是我们需要添加物理系统插件.
1.打开Package Manager > 搜索插件UnityPhysics进行安装
2.注意:安装完后需要重启Unity
3.再在场景中为创建Cube挂载以下组件即可正常展示物理效果了
二.使用Physics组件
为了达到更好的性能我们应当在ECS中使用如以下插件代替Unity传统使用的组件.
创建小球并关其添加以下组件.
使用Physics Shape代替原有的Collider ,使用Physics Body代替原有Rigidbody并且需要挂载ConvertToEntity组件.
三.Demo
下面是使用代码动态创建小球,与之前不同可能是使用了Physics的缘故需要强制创建BlobAssetStore容器
using Unity.Entities;
using UnityEngine;
public class Manager11 : MonoBehaviour
{
//挂载预设
public GameObject spherePrefab;
//资产容器
BlobAssetStore blobAssetStore;
void Start()
{
//初始化容器
blobAssetStore = new BlobAssetStore();
//使用World创建实体
GameObjectConversionSettings tempsettings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, blobAssetStore);
Entity tempEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(spherePrefab, tempsettings);
EntityManager tempEntityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity tempCube = tempEntityManager.Instantiate(tempEntityPrefab);
}
private void OnDestroy()
{
//周期结束销毁容器
blobAssetStore.Dispose();
}
}
四 .批量创建Demo
创建10000个小球,我们可以发现10000个球在Dost中还能保持较高的帧率
我们用一个嵌套循环创建10000个小球
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
public class Manager11 : MonoBehaviour
{
//挂载预设
public GameObject spherePrefab;
public int sphereNum;
public int Interval;
//资产容器
BlobAssetStore blobAssetStore;
void Start()
{
//初始化容器
blobAssetStore = new BlobAssetStore();
//使用World创建实体
GameObjectConversionSettings tempsettings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, blobAssetStore);
Entity tempEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(spherePrefab, tempsettings);
//用于修改位置
Translation tempTranslation = new Translation();
for (int y = 0; y < 40; y++)
{
for (int z = 0; z < 16; z++)
{
for (int x = 0; x < 16; x++)
{
EntityManager tempEntityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity tempCube = tempEntityManager.Instantiate(tempEntityPrefab);
float random = UnityEngine.Random.Range(-0.1f, 0.1f);
tempTranslation.Value = new float3(x * Interval + random, y * Interval, z * Interval - random);
tempEntityManager.SetComponentData(tempCube, tempTranslation);
}
}
}
}
private void OnDestroy()
{
//周期结束销毁容器
blobAssetStore.Dispose();
}
}
五.射线碰撞
在World中获取BuildPhysicsWorld碰撞类中的CollisionWorld碰撞信息
定义RaycastInput写入发射信息后,调用CollisionWorld中的CastRay进行发射并使用RaycastHiy接收信息.