马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、创建12000个弹性球体测试
搜刮:Unity Physics
创建球体预制体如下脚本设置:
- using UnityEngine;
- using Unity.Entities;
- using Unity.Transforms;
- public class PhysicsDemoTest : MonoBehaviour
- {
- public GameObject prefab;
- BlobAssetStore assetStore;
- void Start()
- {
- assetStore = new BlobAssetStore();
- GameObjectConversionSettings settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, assetStore);
- Entity entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, settings);
- EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
- Translation translation = new Translation();
- for (int i = 0; i < 30; i++)
- {
- for (int j = 0; j < 20; j++)
- {
- for (int k = 0; k < 20; k++)
- {
- Entity entity = entityManager.Instantiate(entityPrefab);
- float random = Random.Range(-0.1f, 0.1f);
- translation.Value = new Unity.Mathematics.float3(k * 2 + random, i * 2, j * 2 - random);
- entityManager.SetComponentData(entity, translation);
- }
- }
- }
- }
- void OnDestroy()
- {
- assetStore.Dispose();
- }
- }
复制代码 二、ECS 物理 射线检测
代码只创建一个球体,且球体设置为静态的物体。
 - using UnityEngine;
- using Unity.Entities;
- using Unity.Transforms;
- using Unity.Mathematics;
- using Unity.Physics.Systems;
- using Unity.Physics;
- public class PhysicsDemoTest : MonoBehaviour
- {
- public GameObject prefab;
- BlobAssetStore assetStore;
- void Start()
- {
- assetStore = new BlobAssetStore();
- GameObjectConversionSettings settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, assetStore);
- Entity entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, settings);
- EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
- Translation translation = new Translation();
- Entity entity = entityManager.Instantiate(entityPrefab);
- entityManager.SetName(entity, "球体A");
- float random = UnityEngine.Random.Range(-0.1f, 0.1f);
- translation.Value = new Unity.Mathematics.float3(5, 5, 5);
- entityManager.SetComponentData(entity, translation);
- Entity entity1 = Raycast(Camera.main.transform.position, Input.mousePosition);
- Debug.Log(entityManager.GetName(entity1));
- }
- void OnDestroy()
- {
- assetStore.Dispose();
- }
- void Update()
- {
- if (Input.GetMouseButtonDown(0))
- {
- EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
- UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
- Entity entity1 = Raycast(ray.origin, ray.GetPoint(100));
- Debug.Log(entityManager.GetName(entity1));
- }
- }
- private Entity Raycast(float3 start, float3 end)
- {
- Debug.DrawLine(start, end, Color.red, 2);
- //获取ECS物理系统
- BuildPhysicsWorld buildPhysicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>();
- //碰撞管理
- CollisionWorld collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld;
- //相当于Ray
- RaycastInput raycastInput = new RaycastInput()
- {
- Start = start,
- End = end,
- Filter = CollisionFilter.Default
- };
- //相当于Hit
- Unity.Physics.RaycastHit raycastHit = new Unity.Physics.RaycastHit();
- //使用碰撞管理检测input 输出hit
- if (collisionWorld.CastRay(raycastInput, out raycastHit))
- {
- //使用hit的index作为索引从Bodies数组取到碰撞Body 再取实体
- Entity entity = buildPhysicsWorld.PhysicsWorld.Bodies[raycastHit.RigidBodyIndex].Entity;
- return entity;
- }
- return Entity.Null;
- }
- }
复制代码 利用Job Burst优化代码如下:
注意:不能将BuildPhysicsWorld、CollisionWorld直接转达进Job类,而是将PhysicsWorld传入,利用NativeArray<RigidBody>缓存射线检测到的刚体数组,而不是实体。- using UnityEngine;
- using Unity.Entities;
- using Unity.Transforms;
- using Unity.Mathematics;
- using Unity.Physics.Systems;
- using Unity.Physics;
- using Unity.Jobs;
- using Unity.Collections;
- using Unity.Burst;
- public class PhysicsDemoTest : MonoBehaviour
- {
- public GameObject prefab;
- BlobAssetStore assetStore;
- void Start()
- {
- assetStore = new BlobAssetStore();
- GameObjectConversionSettings settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, assetStore);
- Entity entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, settings);
- EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
- Translation translation = new Translation();
- Entity entity = entityManager.Instantiate(entityPrefab);
- entityManager.SetName(entity, "球体A");
- float random = UnityEngine.Random.Range(-0.1f, 0.1f);
- translation.Value = new Unity.Mathematics.float3(5, 5, 5);
- entityManager.SetComponentData(entity, translation);
- Entity entity1 = Raycast(Camera.main.transform.position, Input.mousePosition);
- Debug.Log(entityManager.GetName(entity1));
- }
- void OnDestroy()
- {
- assetStore.Dispose();
- }
- void Update()
- {
- if (Input.GetMouseButtonDown(0))
- {
- EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
- UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
- //Entity entity1 = Raycast(ray.origin, ray.GetPoint(100));
- //获取ECS物理系统
- BuildPhysicsWorld buildPhysicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>();
- //碰撞管理
- CollisionWorld collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld;
- NativeArray<RigidBody> rigidbodies = new NativeArray<RigidBody>(1, Allocator.TempJob);
- RaycastJob raycastJob = new RaycastJob()
- {
- start = ray.origin,
- end = ray.GetPoint(100),
- physicsWorld = buildPhysicsWorld.PhysicsWorld,
- rigidBodies = rigidbodies
- };
- JobHandle jobHandle = raycastJob.Schedule();
- jobHandle.Complete();
- if (rigidbodies[0].Entity != null)
- {
- Debug.Log(entityManager.GetName(rigidbodies[0].Entity));
- }
- rigidbodies.Dispose();
- }
- }
- [BurstCompile]
- public struct RaycastJob : IJob
- {
- public NativeArray<RigidBody> rigidBodies;
- public float3 start;
- public float3 end;
- public PhysicsWorld physicsWorld;
- public void Execute()
- {
- //相当于Ray
- RaycastInput raycastInput = new RaycastInput()
- {
- Start = start,
- End = end,
- Filter = CollisionFilter.Default
- };
- //相当于Hit
- Unity.Physics.RaycastHit raycastHit = new Unity.Physics.RaycastHit();
- //使用碰撞管理检测input 输出hit
- if (physicsWorld.CollisionWorld.CastRay(raycastInput, out raycastHit))
- {
- //使用hit的index作为索引从Bodies数组取到碰撞Body 再取实体
- rigidBodies[0] = physicsWorld.Bodies[raycastHit.RigidBodyIndex];
- }
- }
- }
- }
复制代码
|