Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Unity.Entities;
- using Unity.Physics;
- namespace HexagonSurvive.HexPhysics
- {
- public struct RaycastTaskData : IComponentData
- {
- public bool isDisposed;
- public RaycastHit hit;
- public RaycastInput input;
- }
- }
- ---------------------------------------------------------------------
- using Unity.Burst;
- using Unity.Collections;
- using Unity.Jobs;
- using Unity.Physics;
- namespace HexagonSurvive.HexPhysics
- {
- [BurstCompile]
- public struct RaycastJob : IJobFor
- {
- [ReadOnly]
- public CollisionWorld collisionWorld;
- public NativeArray<RaycastTaskData> inputs;
- public void Execute(int index)
- {
- if (!inputs[index].isDisposed)
- return;
- RaycastHit hit;
- collisionWorld.CastRay(inputs[index].input, out hit);
- inputs[index] = new RaycastTaskData { hit = hit };
- }
- }
- }
- ---------------------------------------------------------------------
- using System;
- using Unity.Collections;
- using Unity.Entities;
- using Unity.Jobs;
- using Unity.Physics;
- namespace HexagonSurvive.HexPhysics
- {
- [UpdateInGroup(typeof(InitializationSystemGroup))]
- public partial class BatchRaycastSystem : SystemBase
- {
- private JobHandle _jobHandle;
- private RaycastJob _job;
- private NativeArray<RaycastTaskData> _data;
- protected override void OnCreate()
- {
- RequireForUpdate<PhysicsWorldSingleton>();
- _data = new NativeArray<RaycastTaskData>(16, Allocator.Persistent);
- for (int i = 0; i < _data.Length; i++)
- _data[i] = new RaycastTaskData { isDisposed = true };
- }
- protected override void OnUpdate()
- {
- if (_jobHandle.IsCompleted)
- {
- _jobHandle.Complete();
- _jobHandle = new RaycastJob
- {
- collisionWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>().CollisionWorld,
- inputs = _data
- }.Schedule(_data.Length, default);
- }
- }
- protected override void OnDestroy()
- {
- _data.Dispose();
- }
- /// <summary>
- /// Schedule a raycast task and you can get that result next frame.
- /// </summary>
- /// <param name="input">Input data</param>
- /// <returns>Id of the task.</returns>
- /// <exception cref="Exception">Thrown if the buffer is full.</exception>
- public int ScheduleRaycastTask(RaycastInput input)
- {
- for (int i = 0; i < _data.Length; i++)
- {
- if (_data[i].isDisposed)
- {
- _data[i] = new RaycastTaskData { input = input };
- return i;
- }
- }
- throw new Exception("Raycast task buffer is too small! Expand it larger!");
- }
- /// <summary>
- /// Get the hit result of the task by id.
- /// </summary>
- /// <param name="id">Task id</param>
- /// <param name="hit">The hit result</param>
- /// <returns>If the task is done and the return value is valid.</returns>
- public bool TryGetRaycastTaskResult(int id, out RaycastHit hit)
- {
- if (!_jobHandle.IsCompleted)
- {
- hit = default;
- return false;
- }
- hit = _data[id].hit;
- _data[id] = new RaycastTaskData { isDisposed = true };
- return true;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement