Skip to content

Instantly share code, notes, and snippets.

@staggartcreations
Last active January 18, 2024 08:50
Show Gist options
  • Save staggartcreations/d5be958392b21596a22b0dc8e122dc13 to your computer and use it in GitHub Desktop.
Save staggartcreations/d5be958392b21596a22b0dc8e122dc13 to your computer and use it in GitHub Desktop.
Sprite shape animated water volume
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