Skip to content

Instantly share code, notes, and snippets.

@GordeyChernyy
Created March 10, 2020 03:38
Show Gist options
  • Save GordeyChernyy/e8816f0cd3cd56adefb93bc36c5db21b to your computer and use it in GitHub Desktop.
Save GordeyChernyy/e8816f0cd3cd56adefb93bc36c5db21b to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class Verlet : MonoBehaviour
{
class Point
{
public Point(Vector3 pos, Vector3 oldPos)
{
this.pos = pos;
this.oldPos = oldPos;
isFixed = false;
}
public bool isFixed;
public Vector3 pos;
public Vector3 oldPos;
}
class Stick
{
public Stick(Point p1, Point p2)
{
this.p1 = p1;
this.p2 = p2;
length = getDistance();
}
public float getDistance()
{
return Vector3.Distance(p1.pos, p2.pos);
}
public float length;
public Point p1;
public Point p2;
}
[Header("Verlet Settings")]
public int count = 10;
public float stickLength = 0.05f;
List<Point> points = new List<Point>();
List<Stick> sticks = new List<Stick>();
[Header("Physics")]
public float noiseForce = 0.2f;
public float friction = 0.99f;
public bool isNoiseForce = true;
public float gravityForce = -0.02f;
Vector3 gravity;
float seed = 0;
[Header("Line")]
public float lineWidth = 0.2f;
LineRenderer line;
void Start()
{
seed = Random.Range(0f, 1200f);
line = GetComponent<LineRenderer>();
// same
// S1 point S2 ...
// Sticks +------+ | +------+ ...
// Points p1 p2------p1 p2 ...
for (int i = 0; i < count; i++)
{
if (i == 0) // first point
{
Point p = new Point(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
p.isFixed = true;
points.Add(p);
}
else
{
float pos = -i * 0.2f;
Point p = new Point(new Vector3(0, pos + stickLength, 0), new Vector3(0, pos, 0));
points.Add(p);
sticks.Add(new Stick(points[i - 1], points[i]));
}
}
line.positionCount = count;
line.startWidth = lineWidth;
line.endWidth = 0;
}
void Update()
{
points[0].pos = transform.position; // link first point to obj pos
UpdateForces();
UpdatePoints();
UpdateSticks();
}
void UpdateForces()
{
if (isNoiseForce)
{
float x = Mathf.PerlinNoise(Time.time + seed, 0f) - 0.5f;
float z = Mathf.PerlinNoise(Time.time + seed + 120f, 0f) - 0.5f;
gravity = new Vector3(0, gravityForce, 0)*0.01f + new Vector3(x * noiseForce, 0, z * noiseForce)*0.01f;
}
}
void UpdatePoints()
{
int i = 0;
foreach (Point p in points)
{
if (!p.isFixed)
{
Vector3 vel = (p.pos - p.oldPos) * friction;
p.oldPos = p.pos;
p.pos += vel;
p.pos += gravity;
}
line.SetPosition(i++, p.pos);
}
}
void UpdateSticks()
{
foreach (Stick s in sticks)
{
Vector3 p1 = s.p2.pos - s.p1.pos;
float dist = s.getDistance();
float diff = s.length - dist;
float pct = diff / dist / 2.0f;
Vector3 offset = p1 * pct;
s.p1.pos -= offset;
s.p2.pos += offset;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment