using System.Collections.Generic; using Unity.Collections; using Unity.Jobs; using Unity.Mathematics; using UnityEngine; using UnityEngine.Rendering.HighDefinition; [ExecuteInEditMode] public class FitToWaterSurfaceBurst : MonoBehaviour { public int count = 50; public WaterSurface waterSurface; public bool includeDeformation = true; public bool excludeSimulation; public float currentSpeedMultiplier = 1f; public GameObject prefab; private List prefabList; private BoxCollider boxCollider; private NativeArray targetPositionBuffer; private NativeArray errorBuffer; private NativeArray candidatePositionBuffer; private NativeArray projectedPositionWSBuffer; private NativeArray normalWSBuffer; private NativeArray directionBuffer; private NativeArray stepCountBuffer; private void Start() { boxCollider = GetComponent(); Reset(); } private void Reset() { OnDestroy(); targetPositionBuffer = new NativeArray(count, Allocator.Persistent); errorBuffer = new NativeArray(count, Allocator.Persistent); candidatePositionBuffer = new NativeArray(count, Allocator.Persistent); projectedPositionWSBuffer = new NativeArray(count, Allocator.Persistent); normalWSBuffer = new NativeArray(count, Allocator.Persistent); stepCountBuffer = new NativeArray(count, Allocator.Persistent); directionBuffer = new NativeArray(count, Allocator.Persistent); prefabList = new List(); prefabList.Clear(); for (int num = base.transform.childCount; num > 0; num--) { SmartDestroy(base.transform.GetChild(0).gameObject); } for (int i = 0; i < count; i++) { GameObject gameObject = Object.Instantiate(prefab); gameObject.transform.parent = base.transform; gameObject.transform.localPosition = RandomPointInBounds(GetComponent().bounds) - base.transform.position; gameObject.transform.localEulerAngles = new Vector3(-180f, UnityEngine.Random.Range(0, 360), 0f); prefabList.Add(gameObject); } } private void Update() { if (waterSurface == null) { return; } if (!targetPositionBuffer.IsCreated) { Reset(); } WaterSimSearchData wsd = default(WaterSimSearchData); if (waterSurface.FillWaterSearchData(ref wsd)) { for (int i = 0; i < prefabList.Count; i++) { targetPositionBuffer[i] = prefabList[i].transform.position; } IJobParallelForExtensions.Schedule(new WaterSimulationSearchJob { simSearchData = wsd, targetPositionWSBuffer = targetPositionBuffer, startPositionWSBuffer = targetPositionBuffer, maxIterations = 8, error = 0.01f, includeDeformation = includeDeformation, excludeSimulation = excludeSimulation, projectedPositionWSBuffer = projectedPositionWSBuffer, normalWSBuffer = normalWSBuffer, errorBuffer = errorBuffer, candidateLocationWSBuffer = candidatePositionBuffer, directionBuffer = directionBuffer, stepCountBuffer = stepCountBuffer }, count, 1).Complete(); for (int j = 0; j < prefabList.Count; j++) { float3 float5 = projectedPositionWSBuffer[j]; prefabList[j].transform.position = float5 + Time.deltaTime * directionBuffer[j] * currentSpeedMultiplier; } } } private Vector3 RandomPointInBounds(Bounds bounds) { return new Vector3(UnityEngine.Random.Range(bounds.min.x, bounds.max.x), UnityEngine.Random.Range(bounds.min.y, bounds.max.y), UnityEngine.Random.Range(bounds.min.z, bounds.max.z)); } private void OnDestroy() { if (targetPositionBuffer.IsCreated) { targetPositionBuffer.Dispose(); } if (errorBuffer.IsCreated) { errorBuffer.Dispose(); } if (candidatePositionBuffer.IsCreated) { candidatePositionBuffer.Dispose(); } if (projectedPositionWSBuffer.IsCreated) { projectedPositionWSBuffer.Dispose(); } if (normalWSBuffer.IsCreated) { normalWSBuffer.Dispose(); } if (stepCountBuffer.IsCreated) { stepCountBuffer.Dispose(); } if (directionBuffer.IsCreated) { directionBuffer.Dispose(); } } private void OnDisable() { OnDestroy(); } public static void SmartDestroy(Object obj) { if (!(obj == null)) { Object.Destroy(obj); } } }