Created
January 1, 2024 21:06
-
-
Save Oppodelldog/db3a78aef800b8cde7ff12aa56101c85 to your computer and use it in GitHub Desktop.
Unity - Cable Physics
This file contains 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.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