Last active
March 25, 2025 05:36
-
-
Save staggartcreations/d5be958392b21596a22b0dc8e122dc13 to your computer and use it in GitHub Desktop.
Sprite shape animated water volume
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.U2D; | |
[ExecuteInEditMode] | |
public class SpriteWaterShape : MonoBehaviour | |
{ | |
public SpriteShapeController controller; | |
[Space] | |
[Header("Volume")] | |
[Tooltip("Distance between spline points")] | |
public float pointDistance = 0.80f; | |
public float width = 10f; | |
public float height = 5f; | |
[Space] | |
[Header("Wave animation")] | |
[Range(0f,1f)] | |
public float waveHeight = 0.1f; | |
public float waveFrequency = 0.3f; | |
public float waveSpeed = 101f; | |
private int pointCount; | |
private float t; | |
private float sine; | |
private Vector3 pointPosition; | |
private void OnValidate() | |
{ | |
Rebuild(); | |
} | |
public void Rebuild() | |
{ | |
if (!controller) return; | |
pointDistance = Mathf.Max(pointDistance, 0.15f); | |
width = Mathf.Max(width, 0.5f); | |
pointCount = Mathf.CeilToInt(width/pointDistance); | |
controller.spline.Clear(); | |
//Bottom left | |
controller.spline.InsertPointAt(0, new Vector3(-(width*0.5f), -height*0.5f, 0f)); | |
for (int i = 0; i <= pointCount; i++) | |
{ | |
//Normalized distance from left to right (0-1 value) | |
t = (float)i / (float)pointCount; | |
//Insert point along the top of the 'rectangle' | |
controller.spline.InsertPointAt(i, new Vector3((t * width) - (width * 0.5f), height * 0.5f ,0f)); | |
//Corners | |
if (i == 0 || i == pointCount) | |
{ | |
controller.spline.SetTangentMode(i, ShapeTangentMode.Broken); | |
//Top left | |
if (i == 0) | |
{ | |
controller.spline.SetLeftTangent(i, Vector3.down); | |
controller.spline.SetRightTangent(i, Vector3.right * (pointDistance * 0.5f)); | |
} | |
//Top right | |
if (i == pointCount) | |
{ | |
controller.spline.SetLeftTangent(i, Vector3.left * (pointDistance * 0.5f)); | |
controller.spline.SetRightTangent(i, Vector3.down); | |
} | |
} | |
else | |
{ | |
controller.spline.SetTangentMode(i, ShapeTangentMode.Continuous); | |
//Place tangents flat and half way towards next/previous point (smooth sine curve) | |
controller.spline.SetLeftTangent(i, Vector3.left * (pointDistance * 0.5f)); | |
controller.spline.SetRightTangent(i, Vector3.right * (pointDistance * 0.5f)); | |
} | |
} | |
//Bottom right | |
controller.spline.InsertPointAt(pointCount+1, new Vector3(width * 0.5f, -height*0.5f, 0f)); | |
controller.RefreshSpriteShape(); | |
} | |
private void Update() | |
{ | |
if (!controller) return; | |
//Modify all points except the first and last (bottom corners) | |
for (int i = 1; i <= pointCount-1; i++) | |
{ | |
t = (float) i / pointCount; | |
sine = Mathf.Sin((t * (width/waveFrequency)) + (Time.time * waveSpeed)) * waveHeight; | |
pointPosition.x = (t * width) - (width * 0.5f); //Basically unchanged | |
pointPosition.y = sine + (height * 0.5f); | |
pointPosition.z = 0; | |
controller.spline.SetPosition(i, pointPosition); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment