/// <summary> /// Sets up the manager. /// </summary> private void Initialize() { _instance = this; #if UNITY_EDITOR _recompileMarker = new RecompiledMarker(); #endif _isDestroyed = false; UpdateCameraEvents(Camera.allCameras); }
private void OnEnable() { #if UNITY_EDITOR if (_recompileMarker == null) { Initialize(); _recompileMarker = new RecompiledMarker(); } #endif }
private void LateUpdate() { if (_recompileMarker == null) { Initialize(); _recompileMarker = new RecompiledMarker(); } UpdateCameraEvents(SceneView.GetAllSceneCameras()); }
private readonly Vector3 _upDirection = Vector3.up; // Force direction is towards the XZ plane up private void Start() { _isReady = false; _recompileMarker = new RecompiledMarker(); _transform = GetComponent <Transform>(); _rigidbody = GetComponent <Rigidbody>(); RecalculateVoxels(); RecalculateCache(); }
public void ResetShip() { _isReady = false; _recompileMarker = new RecompiledMarker(); _transform = GetComponent <Transform>(); _rigidbody = GetComponent <Rigidbody>(); RecalculateVoxels(); RecalculateCache(); }
/// <summary> /// Buoyancy calculation step. /// </summary> private void FixedUpdate() { // Happens on assembly reload if (_recompileMarker == null) { RecalculateVoxels(); _water = null; _recompileMarker = new RecompiledMarker(); } // Failsafe if (_water == null || _density < 0.01f || !_isReady) { _rigidbody.drag = _dragNonFluid; _rigidbody.angularDrag = _angularDragNonFluid; return; } float invDoubleVoxelSize = 1f / (2f * _voxelSize); DynamicWater dynamicWater = _water as DynamicWater; bool solverCanInteract = dynamicWater != null && dynamicWater.Solver.CanInteract; for (int i = 0; i < _voxelsLength; i++) { Vector3 wp = _transform.TransformPoint(_buoyancyVoxels[i].Position); float waterLevel = _water.GetWaterLevel(wp.x, wp.y, wp.z); // No force is applied to the points outside the fluid if (waterLevel != float.NegativeInfinity && (wp.y - _voxelSize / 1f < waterLevel)) { Vector3 velocity = _rigidbody.GetPointVelocity(wp); // k == 1 when the voxel is fully submerged // k == 0 when the voxel is fully outside float k = (waterLevel - wp.y) * invDoubleVoxelSize + 0.5f; // Create the splash when the point has passed the water surface. if (_buoyancyVoxels[i].IsOnColliderEdge) { if (!_buoyancyVoxels[i].HadPassedWater && (k < 1f && k > 0f)) { // Scaling and limiting the splash force if (solverCanInteract) { float force = FastFunctions.FastVector3Magnitude(velocity) * _splashForceFactorNormalized; if (force > _maxSplashForceNormalized) { force = _maxSplashForceNormalized; } if (force > 0.0075f) { _water.CreateSplash(wp, _voxelSize, force); } } _buoyancyVoxels[i].HadPassedWater = true; } else { _buoyancyVoxels[i].HadPassedWater = false; } } k = (k > 1f) ? 1f : (k < 0f) ? 0f : k; _subMergedVolume += k; // Calculating the actual force for this point depending oh how much // the point is submerged into the fluid Vector3 archimedesForce; archimedesForce.x = k * _voxelArchimedesForce.x; archimedesForce.y = k * _voxelArchimedesForce.y; archimedesForce.z = k * _voxelArchimedesForce.z; // Applying the local force _rigidbody.AddForceAtPosition(archimedesForce, wp, ForceMode.Impulse); } } // Normalizing the submerged volume // 0 - object is fully outside the water // 1 - object is fully submerged _subMergedVolume /= _voxelsLength; const float threshold = 0.01f; // Sending the message to other components if (_subMergedVolumePrev < threshold && _subMergedVolume >= threshold) { SendMessage("OnFluidVolumeEnter", _water, SendMessageOptions.DontRequireReceiver); } else if (_subMergedVolumePrev >= threshold && _subMergedVolume < threshold) { SendMessage("OnFluidVolumeExit", _water, SendMessageOptions.DontRequireReceiver); } _subMergedVolumePrev = _subMergedVolume; // Calculating the drag _rigidbody.drag = Mathf.Lerp(_rigidbody.drag, _subMergedVolume > 0.0001f ? _dragNonFluid + _dragInFluid : _dragNonFluid, 8f * Time.deltaTime); _rigidbody.angularDrag = Mathf.Lerp(_rigidbody.angularDrag, _subMergedVolume > 0.0001f ? _angularDragNonFluid + _angularDragInFluid : _angularDragNonFluid, 8f * Time.deltaTime); }
private readonly Vector3 _upDirection = Vector3.up; // Force direction is towards the XZ plane up private void Start() { _isReady = false; _recompileMarker = new RecompiledMarker(); _transform = GetComponent<Transform>(); _rigidbody = GetComponent<Rigidbody>(); RecalculateVoxels(); RecalculateCache(); }
private void FixedUpdate() { if (!Application.isPlaying) { return; } if (_recompiledMarker == null) { Initialize(); _recompiledMarker = new RecompiledMarker(); } if (Application.isEditor) { UpdateComponents(); } #if !ARBITRARY_ROTATIONS _cachedPosition = _transform.position; _cachedLossyScale = _transform.lossyScale; #endif StepSimulation(); }
private void Start() { _recompiledMarker = new RecompiledMarker(); Initialize(); }
/// <summary> /// Buoyancy calculation step. /// </summary> private void FixedUpdate() { // Happens on assembly reload if (_recompileMarker == null) { RecalculateVoxels(); _water = null; _recompileMarker = new RecompiledMarker(); } // Failsafe if (_water == null || _density < 0.01f || !_isReady) { _rigidbody.drag = _dragNonFluid; _rigidbody.angularDrag = _angularDragNonFluid; return; } float invDoubleVoxelSize = 1f / (2f * _voxelSize); DynamicWater dynamicWater = _water as DynamicWater; bool solverCanInteract = dynamicWater != null && dynamicWater.Solver.CanInteract; for (int i = 0; i < _voxelsLength; i++) { Vector3 wp = _transform.TransformPoint(_buoyancyVoxels[i].Position); float waterLevel = _water.GetWaterLevel(wp.x, wp.y, wp.z); // No force is applied to the points outside the fluid if (waterLevel != float.NegativeInfinity && (wp.y - _voxelSize / 1f < waterLevel)) { Vector3 velocity = _rigidbody.GetPointVelocity(wp); // k == 1 when the voxel is fully submerged // k == 0 when the voxel is fully outside float k = (waterLevel - wp.y) * invDoubleVoxelSize + 0.5f; // Create the splash when the point has passed the water surface. if (_buoyancyVoxels[i].IsOnColliderEdge) { if (!_buoyancyVoxels[i].HadPassedWater && (k <1f && k> 0f)) { // Scaling and limiting the splash force if (solverCanInteract) { float force = FastFunctions.FastVector3Magnitude(velocity) * _splashForceFactorNormalized; if (force > _maxSplashForceNormalized) { force = _maxSplashForceNormalized; } if (force > 0.0075f) { _water.CreateSplash(wp, _voxelSize, force); } } _buoyancyVoxels[i].HadPassedWater = true; } else { _buoyancyVoxels[i].HadPassedWater = false; } } k = (k > 1f) ? 1f : (k < 0f) ? 0f : k; _subMergedVolume += k; // Calculating the actual force for this point depending oh how much // the point is submerged into the fluid Vector3 archimedesForce; archimedesForce.x = k * _voxelArchimedesForce.x; archimedesForce.y = k * _voxelArchimedesForce.y; archimedesForce.z = k * _voxelArchimedesForce.z; // Applying the local force _rigidbody.AddForceAtPosition(archimedesForce, wp, ForceMode.Impulse); } } // Normalizing the submerged volume // 0 - object is fully outside the water // 1 - object is fully submerged _subMergedVolume /= _voxelsLength; const float threshold = 0.01f; // Sending the message to other components if (_subMergedVolumePrev < threshold && _subMergedVolume >= threshold) { SendMessage("OnFluidVolumeEnter", _water, SendMessageOptions.DontRequireReceiver); } else if (_subMergedVolumePrev >= threshold && _subMergedVolume < threshold) { SendMessage("OnFluidVolumeExit", _water, SendMessageOptions.DontRequireReceiver); } _subMergedVolumePrev = _subMergedVolume; // Calculating the drag _rigidbody.drag = Mathf.Lerp(_rigidbody.drag, _subMergedVolume > 0.0001f ? _dragNonFluid + _dragInFluid : _dragNonFluid, 8f * Time.deltaTime); _rigidbody.angularDrag = Mathf.Lerp(_rigidbody.angularDrag, _subMergedVolume > 0.0001f ? _angularDragNonFluid + _angularDragInFluid : _angularDragNonFluid, 8f * Time.deltaTime); }