Skip to content

Instantly share code, notes, and snippets.

@Oppodelldog
Created January 1, 2024 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Oppodelldog/db3a78aef800b8cde7ff12aa56101c85 to your computer and use it in GitHub Desktop.
Save Oppodelldog/db3a78aef800b8cde7ff12aa56101c85 to your computer and use it in GitHub Desktop.
Unity - Cable Physics
using System.Collections.Generic;
using UnityEngine;
public class Chain : MonoBehaviour
{
public float width = 0.1f;
public int segments = 10;
public Material material;
public float mass = 0.1f;
public float spring = 10f;
public float damper = 10f;
public float limit = 0.1f;
public float drag = 0.2f;
public float angularDrag = 0.1f;
public Transform start;
public Transform end;
private List<Rigidbody> _rigidbodies = new();
private LineRenderer _lineRenderer;
void Start()
{
if (segments < 2) segments = 2;
var startPosition = start.position;
var endPosition = end.position;
_lineRenderer = gameObject.AddComponent<LineRenderer>();
_lineRenderer.positionCount = segments;
_lineRenderer.startWidth = width;
_lineRenderer.endWidth = width;
_lineRenderer.material = material;
for (var i = 0; i < segments; i++)
{
var segment = new GameObject("Segment" + i);
segment.transform.position = Vector3.Lerp(startPosition, endPosition, (float) i / (segments - 1));
segment.transform.parent = transform;
var sc = segment.gameObject.AddComponent<SphereCollider>();
sc.radius = width / 2f;
var rb = segment.gameObject.AddComponent<Rigidbody>();
rb.mass = mass;
rb.useGravity = true;
rb.isKinematic = false;
rb.drag = drag;
rb.angularDrag = angularDrag;
_rigidbodies.Add(rb);
if(i>0 && i < segments)
{
var joint = segment.gameObject.AddComponent<ConfigurableJoint>();
joint.connectedBody = _rigidbodies[i - 1];
joint.xMotion = ConfigurableJointMotion.Limited;
joint.yMotion = ConfigurableJointMotion.Limited;
joint.zMotion = ConfigurableJointMotion.Limited;
joint.angularXMotion = ConfigurableJointMotion.Locked;
joint.angularYMotion = ConfigurableJointMotion.Locked;
joint.angularZMotion = ConfigurableJointMotion.Locked;
joint.linearLimitSpring = new SoftJointLimitSpring {spring = spring, damper = damper};
joint.linearLimit = new SoftJointLimit {limit = limit};
}
}
var firstRb = _rigidbodies[0];
var lastRb = _rigidbodies[_rigidbodies.Count - 1];
// first and last rigidbodies are kinematic
firstRb.isKinematic = true;
lastRb.isKinematic = true;
// first and last segments are connected to start and end
firstRb.transform.position = startPosition;
firstRb.transform.parent = start;
lastRb.transform.position = endPosition;
lastRb.transform.parent = end;
}
void Update()
{
for (int i = 0; i < _rigidbodies.Count; i++)
{
_lineRenderer.SetPosition(i, _rigidbodies[i].transform.position);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment