using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.U2D; public class WaterShapeController : MonoBehaviour { [SerializeField] private GameObject wavePointPref; [SerializeField] private float _springStiffness = 0.1f; [SerializeField] private float _dampening = 0.3f; [SerializeField] private List _springs = new List(); [SerializeField] private SpriteShapeController _spriteShapeController; [SerializeField] private int _wavesCount = 6; [SerializeField] private GameObject _wavePoints; private int _cornersCount = 2; private float _spread = 0.006f; private void SetWaves() { Spline waterSpline = _spriteShapeController.spline; var waterPointsCount = waterSpline.GetPointCount(); for (int count = _cornersCount; count < waterPointsCount - _cornersCount; count++) { waterSpline.RemovePointAt(_cornersCount); } Vector3 waterTopLeftCorner = waterSpline.GetPosition(1); Vector3 waterTopRightCorner = waterSpline.GetPosition(2); float waterWidth = waterTopRightCorner.x - waterTopLeftCorner.x; float spacingPerWawe = waterWidth / (_wavesCount + 1); for (int count = _wavesCount; count > 0; count--) { int index = _cornersCount; float xPosition=waterTopLeftCorner.x+(spacingPerWawe * count); Vector3 wavePoint=new Vector3(xPosition,waterTopLeftCorner.y,waterTopLeftCorner.z); waterSpline.InsertPointAt(index, wavePoint ); waterSpline.SetHeight(index, 0f); waterSpline.SetCorner(index, false); } CreateSprings(waterSpline); Splash(2, 0.1f); } private void CreateSprings(Spline waterSpline) { _springs = new List(); for(int idx=0;idx<_wavesCount+1; idx++) { int index = idx + 1; Smoothen(waterSpline, index); GameObject wavePoint = Instantiate(wavePointPref, _wavePoints.transform, false); wavePoint.transform.position = waterSpline.GetPosition(index); WaterSpring waterSpring=wavePoint.GetComponent(); waterSpring.Init(_spriteShapeController); _springs.Add( waterSpring ); } } private void Smoothen(Spline waterSpline, int index) { Vector3 position = waterSpline.GetPosition(index); Vector3 positionPrev = position; Vector3 positionNext = position; if (index > 1) { positionPrev = waterSpline.GetPosition(index - 1); } if (index - 1 <= _wavesCount) { positionNext = waterSpline.GetPosition(index + 1); } Vector3 forward = gameObject.transform.forward; float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f; Vector3 leftTangent = (positionPrev - position).normalized * scale; Vector3 rightTangent = (positionNext - position).normalized * scale; SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent); waterSpline.SetLeftTangent(index, leftTangent); waterSpline.SetRightTangent(index, rightTangent); } private void UpdateSprings() { int springsCount = _springs.Count; float[] left_deltas = new float[springsCount]; float[] right_deltas = new float[springsCount]; for (int index = 0; index < springsCount; index++) { if (index > 0) { left_deltas[index] = _spread * (_springs[index].Height - _springs[index - 1].Height); _springs[index - 1].Velocity += left_deltas[index]; } if (index =0 && index<_springs.Count) { _springs[index].Velocity += speed; } } //On Enable for example purposes void OnEnable() { StartCoroutine(CreateWaves()); foreach (WaterSpring waterSpringComponent in _springs) { waterSpringComponent.Init(_spriteShapeController); } } IEnumerator CreateWaves() { foreach (Transform child in _wavePoints.transform) { StartCoroutine(Destroy(child.gameObject)); } yield return null; SetWaves(); yield return null; } IEnumerator Destroy(GameObject go) { yield return null; DestroyImmediate(go); } private void FixedUpdate() { foreach (WaterSpring spring in _springs) { spring.WaveSpringUpdate(_springStiffness, _dampening); spring.WavePointUpdate(); } UpdateSprings(); } }