void CleanupMultithreadRaycasts() { #if UNITY_2018_1_OR_NEWER if (_multithreadRaycasts == null) { return; } _multithreadRaycasts.raycasts.Dispose(); _multithreadRaycasts.hits.Dispose(); _multithreadRaycasts = null; #endif }
bool CalculateLineOfSight3D(Vector3 eye, float radius, float penetration, LayerMask layermask, Vector3 up, Vector3 forward) { bool hashit = false; float angle = 360.0f / _distances.Length; #if UNITY_2018_1_OR_NEWER if (multithreading) { // make sure native arrays are ready if (_multithreadRaycasts == null) { _multithreadRaycasts = new FogOfWarUnitRaycasts() { raycasts = new NativeArray <RaycastCommand>(lineOfSightRaycastCount, Allocator.Persistent), hits = new NativeArray <RaycastHit>(lineOfSightRaycastCount, Allocator.Persistent) }; } else if (_multithreadRaycasts.raycasts.Length != lineOfSightRaycastCount) { _multithreadRaycasts.raycasts = new NativeArray <RaycastCommand>(lineOfSightRaycastCount, Allocator.Persistent); _multithreadRaycasts.hits = new NativeArray <RaycastHit>(lineOfSightRaycastCount, Allocator.Persistent); } // prepare raycasts for (int i = 0; i < _distances.Length; ++i) { Vector3 dir = Quaternion.AngleAxis(angle * i, up) * forward; _multithreadRaycasts.raycasts[i] = new RaycastCommand(eye, dir, radius, layermask); } // perform raycasts RaycastCommand.ScheduleBatch(_multithreadRaycasts.raycasts, _multithreadRaycasts.hits, 1).Complete(); // copy results for (int i = 0; i < _distances.Length; ++i) { if (_multithreadRaycasts.hits[i].collider != null) { _distances[i] = (_multithreadRaycasts.hits[i].distance + penetration) / radius; if (_distances[i] < 1) { hashit = true; } else { _distances[i] = 1; } } else { _distances[i] = 1; } } } else #endif { CleanupMultithreadRaycasts(); for (int i = 0; i < _distances.Length; ++i) { Vector3 dir = Quaternion.AngleAxis(angle * i, up) * forward; if (Physics.Raycast(eye, dir, out RaycastHit hit, radius, layermask)) { _distances[i] = (hit.distance + penetration) / radius; if (_distances[i] < 1) { hashit = true; } else { _distances[i] = 1; } }