private void OnTriggerExit(Collider otherCollider) { // Making sure the object we have left is DynamicWater if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider == _water.Collider) { _water = null; } }
private void OnTriggerEnter(Collider otherCollider) { // Making sure the object we have entered is DynamicWater if (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName)) { _water = otherCollider.gameObject.GetComponent <DynamicWater>(); } }
/// <summary> /// Called when BuoyantObject enters the water. /// </summary> /// <param name="eventWater"> /// The FluidVolume which the object has entered. /// </param> public void OnFluidVolumeEnter(IDynamicWaterFluidVolume eventWater) { _water = eventWater as IDynamicWaterSettings; if (_water == null) { return; } if (_water.PlaneCollider != null) { SpawnSplash(SplashPrefab, _water.PlaneCollider.ClosestPointOnBounds(transform.position)); } }
/// <summary> /// Checking if we have left the fluid volume. /// </summary> private void OnTriggerExit(Collider otherCollider) { if (!_isReady) { return; } if (_water != null && otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider == _water.Collider) { _water = null; } }
/// <summary> /// Checking if we are staying in the fluid volume. /// </summary> private void OnTriggerStay(Collider otherCollider) { if (!_isReady) { return; } if (_water == null || (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider != _water.Collider)) { IDynamicWaterFluidVolume water = otherCollider.gameObject.GetComponent <FluidVolume>() ?? otherCollider.gameObject.GetComponent <DynamicWater>(); if (water != null) { _water = water; RecalculateCache(); } } }
private void OnTriggerEnter(Collider otherCollider) { // Making sure the object we have entered is DynamicWater if (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName)) { _water = otherCollider.gameObject.GetComponent<DynamicWater>(); } }
/// <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); }
/// <summary> /// Checking if we are staying in the fluid volume. /// </summary> private void OnTriggerStay(Collider otherCollider) { if (!_isReady) { return; } if (_water == null || (otherCollider.CompareTag(FluidVolume.DynamicWaterTagName) && otherCollider != _water.Collider)) { IDynamicWaterFluidVolume water = otherCollider.gameObject.GetComponent<FluidVolume>() ?? otherCollider.gameObject.GetComponent<DynamicWater>(); if (water != null) { _water = water; 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); }