/// <summary> /// 该接口要达到一定量级性能才会更优 /// </summary> /// <param name="bounds"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static RaycastHit[] RaycastGrid(Vector3 center, int width, int height, int layerMask = -1, int maxHists = 1, int maxHeight = 1000) { var results = new NativeArray <RaycastHit>(width * height * maxHists, Allocator.TempJob); var commands = new NativeArray <RaycastCommand>(width * height, Allocator.TempJob); var halfWidth = (width - 1) * 0.5f; var halfHeight = (height - 1) * 0.5f; var offsetHeight = Vector3.up * maxHeight; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { var rayCenter = center - new Vector3(halfWidth, center.y, halfHeight) + new Vector3(i, 0, j); commands[i + j * width] = new RaycastCommand(rayCenter + offsetHeight, Vector3.down, layerMask: layerMask); } } if (maxHists == 1) { var handle = RaycastCommand.ScheduleBatch(commands, results, 1); handle.Complete(); } else { var handle = new RaycastAllCommand(commands, results, maxHists); handle.Schedule(default).Complete();
public void NeedForMinStepTest(bool shouldFail) { var maxHits = 4; var rayStart = new Vector3(0f, 4f, 0f); var meshConvexCommand = new RaycastCommand(meshConvexCollider.transform.position + rayStart, Vector3.down, 8f); var commandsArray = new RaycastCommand[] { meshConvexCommand }; var commands = new NativeArray <RaycastCommand>(commandsArray, Allocator.TempJob); var commandHits = new NativeArray <RaycastHit>(commands.Length * maxHits, Allocator.TempJob); //setting minStep to 0f var raycastAllCommand = new RaycastAllCommand(commands, commandHits, maxHits, shouldFail ? 0f : 0.0001f); raycastAllCommand.Schedule(default(JobHandle)).Complete(); Assert.AreEqual(meshConvexCollider, commandHits[0].collider); var collider = commandHits[1].collider; if (shouldFail) { Assert.IsNotNull(collider, "RaycastHit in corner point behaviour changed, minStep may be no longer required"); } else { Assert.IsNull(collider); } commandHits.Dispose(); commands.Dispose(); raycastAllCommand.Dispose(); }
// Update is called once per frame void Update() { if (walkMonsterSize <= 0.01 || sideCount < 1) { return; } //if (hits == null || !hits.IsCreated) //{ // hits = new NativeArray<RaycastHit>(sideCount * sideCount * maxHits, Allocator.Persistent); //} if (hits.Length != sideCount * sideCount * maxHits || !hits.IsCreated || !pollsRaycastHits.IsCreated || !pollsFreePoints.IsCreated || !pollsBlockedPoints.IsCreated || !pollPositions.IsCreated || !raycasts.IsCreated) { DisposeAllPersistentData(); SetUpdateData(); return; } pollsRaycastHits.Clear(); pollsFreePoints.Clear(); pollsBlockedPoints.Clear(); float spacing = (1f / (sideCount - 1)) * walkMonsterSize; for (int y = 0; y < sideCount; y++) { for (int x = 0; x < sideCount; x++) { Vector3 point = transform.position + new Vector3(0 - (walkMonsterSize / 2) + x * spacing, 0, 0 - (walkMonsterSize / 2) + y * spacing); point.y = maxHeight; raycasts[y * sideCount + x] = new RaycastCommand(point, Vector3.down); } } raycastAllCommand = new RaycastAllCommand(raycasts, hits, maxHits); JobHandle raycastAllCommandJob = raycastAllCommand.Schedule(default);
public void CommonHitsTest([Values(2, 3, 4)] int maxHits) { var rayStart = new Vector3(0f, 4f, 0f); var cubeCommand = new RaycastCommand(cubeCollider.transform.position + rayStart, Vector3.down); var meshCubeCommand = new RaycastCommand(meshCubeCollider.transform.position + rayStart, Vector3.down); var meshConvexCommand = new RaycastCommand(meshConvexCollider.transform.position + rayStart, Vector3.down); var emptyCommand = new RaycastCommand(new Vector3(30f, 0f, 0f) + rayStart, Vector3.down); var commandsArray = new RaycastCommand[] { cubeCommand, meshCubeCommand, emptyCommand, meshConvexCommand }; var commands = new NativeArray <RaycastCommand>(commandsArray, Allocator.TempJob); var commandHits = new NativeArray <RaycastHit>(commands.Length * maxHits, Allocator.TempJob); var raycastAllCommand = new RaycastAllCommand(commands, commandHits, maxHits); raycastAllCommand.Schedule(default(JobHandle)).Complete(); Assert.AreEqual(cubeCollider, commandHits[maxHits * 0].collider); Assert.AreEqual(meshCubeCollider, commandHits[maxHits * 1].collider); Assert.AreEqual(null, commandHits[maxHits * 2].collider); Assert.AreEqual(meshConvexCollider, commandHits[maxHits * 3].collider); var physicsHits = new RaycastHit[maxHits]; for (int i = 0; i < commands.Length; i++) { var physicsHitsCount = Physics.RaycastNonAlloc(commands[i].from, commands[i].direction, physicsHits); SortHits(physicsHits, physicsHitsCount); for (int j = 0; j < physicsHitsCount; j++) { var physicsHit = physicsHits[j]; var commandHit = commandHits[i * maxHits + j]; RaycastHitEquality.AssertEqual(physicsHit, commandHit); } if (physicsHitsCount < maxHits) { Assert.AreEqual(null, commandHits[i * maxHits + physicsHitsCount].collider); } } commandHits.Dispose(); commands.Dispose(); raycastAllCommand.Dispose(); }