/// <summary> /// Generate a ripple at a particular position. /// </summary> /// <param name="position">Ripple position.</param> /// <param name="disturbanceFactor">Range: [0..1]: The disturbance is linearly interpolated between the minimum disturbance and the maximum disturbance by this factor.</param> /// <param name="pullWaterDown">Pull water down or up?</param> /// <param name="playSoundEffect">Play the sound effect.</param> /// <param name="playParticleEffect">Play the particle effect.</param> /// <param name="smooth">Disturb neighbor vertices to create a smoother ripple (wave).</param> /// <param name="smoothingFactor">Range: [0..1]: The amount of disturbance to apply to neighbor vertices.</param> public void GenerateRipple(Vector2 position, float disturbanceFactor, bool pullWaterDown, bool playSoundEffect, bool playParticleEffect, bool smooth, float smoothingFactor = 0.5f) { float xPosition = _mainModule.TransformWorldToLocal(position).x; float leftBoundary = _simulationModule.LeftBoundary; float rightBoundary = _simulationModule.RightBoundary; int surfaceVerticesCount = _meshModule.SurfaceVerticesCount; int startIndex = _simulationModule.IsUsingCustomBoundaries ? 1 : 0; int endIndex = _simulationModule.IsUsingCustomBoundaries ? surfaceVerticesCount - 2 : surfaceVerticesCount - 1; if (xPosition < leftBoundary || xPosition > rightBoundary) { return; } float disturbance = Mathf.Lerp(_minimumDisturbance, _maximumDisturbance, Mathf.Clamp01(disturbanceFactor)); float velocity = (pullWaterDown ? -1f : 1f) * _simulationModule.StiffnessSquareRoot * disturbance; float delta = (xPosition - leftBoundary) * _meshModule.SubdivisionsPerUnit; int nearestVertexIndex = startIndex + Mathf.RoundToInt(delta); var velocities = _simulationModule.Velocities; velocities[nearestVertexIndex] += velocity; if (smooth) { smoothingFactor = Mathf.Clamp01(smoothingFactor); float smoothedVelocity = velocity * smoothingFactor; int previousNearestIndex = nearestVertexIndex - 1; if (previousNearestIndex >= startIndex) { velocities[previousNearestIndex] += smoothedVelocity; } int nextNearestIndex = nearestVertexIndex + 1; if (nextNearestIndex <= endIndex) { velocities[nextNearestIndex] += smoothedVelocity; } } _simulationModule.MarkVelocitiesArrayAsChanged(); Vector3 spawnPosition = _mainModule.TransformLocalToWorld(new Vector2(xPosition, _mainModule.Height * 0.5f)); if (playParticleEffect) { _particleEffect.PlayParticleEffect(spawnPosition); } if (playSoundEffect) { _soundEffect.PlaySoundEffect(spawnPosition, disturbanceFactor); } }
/// <summary> /// Generate a ripple at a particular position. /// </summary> /// <param name="position">Ripple position.</param> /// <param name="disturbanceFactor">Range: [0..1]: The disturbance is linearly interpolated between the minimum disturbance and the maximum disturbance by this factor.</param> /// <param name="pullWaterDown">Pull water down or up?</param> /// <param name="playSoundEffect">Play the sound effect.</param> /// <param name="playParticleEffect">Play the particle effect.</param> /// <param name="smoothRipple">Disturb neighbor vertices to create a smoother ripple (wave).</param> /// <param name="smoothingFactor">Range: [0..1]: The amount of disturbance to apply to neighbor vertices.</param> public void GenerateRipple(Vector2 position, float disturbanceFactor, bool pullWaterDown, bool playSoundEffect, bool playParticleEffect, bool smoothRipple, float smoothingFactor = 0.5f) { float xPosition = _mainModule.TransformPointWorldToLocal(position).x; float leftBoundary = _simulationModule.LeftBoundary; float rightBoundary = _simulationModule.RightBoundary; int surfaceVertexCount = _meshModule.SurfaceVerticesCount; int leftMostSurfaceVertexIndex = _simulationModule.IsUsingCustomBoundaries ? 1 : 0; int rightMostSurfaceVertexIndex = _simulationModule.IsUsingCustomBoundaries ? surfaceVertexCount - 2 : surfaceVertexCount - 1; if (xPosition < leftBoundary || xPosition > rightBoundary) { return; } float disturbance = (pullWaterDown ? -1f : 1f) * Mathf.Lerp(_minimumDisturbance, _maximumDisturbance, Mathf.Clamp01(disturbanceFactor)); float subdivisionsPerUnit = (surfaceVertexCount - (_simulationModule.IsUsingCustomBoundaries ? 3 : 1)) / (rightBoundary - leftBoundary); float delta = (xPosition - leftBoundary) * subdivisionsPerUnit; int nearestVertexIndex = leftMostSurfaceVertexIndex + Mathf.RoundToInt(delta); _simulationModule.DisturbSurfaceVertex(nearestVertexIndex, disturbance); if (smoothRipple) { smoothingFactor = Mathf.Clamp01(smoothingFactor); float smoothedDisturbance = disturbance * smoothingFactor; int previousNearestIndex = nearestVertexIndex - 1; if (previousNearestIndex >= leftMostSurfaceVertexIndex) { _simulationModule.DisturbSurfaceVertex(previousNearestIndex, smoothedDisturbance); } int nextNearestIndex = nearestVertexIndex + 1; if (nextNearestIndex <= rightMostSurfaceVertexIndex) { _simulationModule.DisturbSurfaceVertex(nextNearestIndex, smoothedDisturbance); } } Vector3 spawnPosition = _mainModule.TransformPointLocalToWorld(new Vector3(xPosition, _mainModule.Height * 0.5f)); if (playParticleEffect) { _particleEffect.PlayParticleEffect(spawnPosition); } if (playSoundEffect) { _soundEffect.PlaySoundEffect(spawnPosition, disturbanceFactor); } }
internal void PhysicsUpdate(float deltaTime) { if (!_isActive || (!_updateWhenOffscreen && !_mainModule.IsVisible)) { return; } _elapsedTime += deltaTime; if (_elapsedTime >= _currentInterval) { if (_randomizeRipplesSourcePositions) { RandomizeIndices(); } int surfaceVerticesCount = _meshModule.SurfaceVerticesCount; int startIndex = _simulationModule.IsUsingCustomBoundaries ? 1 : 0; int endIndex = _simulationModule.IsUsingCustomBoundaries ? surfaceVerticesCount - 2 : surfaceVerticesCount - 1; Vector3[] vertices = _meshModule.Vertices; float[] velocities = _simulationModule.Velocities; bool playSoundEffect = _soundEffect.IsActive; bool playParticleEffect = _particleEffect.IsActive; for (int i = 0, imax = _ripplesSourcesIndices.Count; i < imax; i++) { int index = _ripplesSourcesIndices[i]; float disturbance = _randomizeDisturbance ? Random.Range(_minimumDisturbance, _maximumDisturbance) : _disturbance; disturbance *= _simulationModule.StiffnessSquareRoot; velocities[index] -= disturbance; if (_smoothRipples) { float smoothedDisturbance = disturbance * _smoothingFactor; int previousIndex, nextIndex; previousIndex = index - 1; nextIndex = index + 1; if (previousIndex >= startIndex) { velocities[previousIndex] -= smoothedDisturbance; } if (nextIndex <= endIndex) { velocities[nextIndex] -= smoothedDisturbance; } } #if UNITY_EDITOR if (!Application.isPlaying) { continue; } #endif if (_soundEffect.IsActive || _particleEffect.IsActive) { Vector3 spawnPosition = _mainModule.TransformPointLocalToWorld(vertices[index]); if (playParticleEffect) { _particleEffect.PlayParticleEffect(spawnPosition); } if (playSoundEffect) { float disturbanceFactor = Mathf.InverseLerp(_minimumDisturbance, _maximumDisturbance, disturbance); _soundEffect.PlaySoundEffect(spawnPosition, disturbanceFactor); } } } _currentInterval = _randomizeTimeInterval ? Random.Range(_minimumTimeInterval, _maximumTimeInterval) : _timeInterval; _elapsedTime = 0f; _simulationModule.MarkVelocitiesArrayAsChanged(); } }