Skip to content

Instantly share code, notes, and snippets.

@ditzel
Created July 14, 2018 12:43
Show Gist options
  • Select an option

  • Save ditzel/ae6ebc115d767da9a5a1e1f70dee27e5 to your computer and use it in GitHub Desktop.

Select an option

Save ditzel/ae6ebc115d767da9a5a1e1f70dee27e5 to your computer and use it in GitHub Desktop.

Revisions

  1. ditzel created this gist Jul 14, 2018.
    38 changes: 38 additions & 0 deletions DistanceJoint3D.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    using UnityEngine;

    public class DistanceJoint3D : MonoBehaviour {

    public Transform ConnectedRigidbody;
    public bool DetermineDistanceOnStart = true;
    public float Distance;
    public float Spring = 0.1f;
    public float Damper = 5f;

    protected Rigidbody Rigidbody;

    void Awake()
    {
    Rigidbody = GetComponent<Rigidbody>();
    }

    void Start()
    {
    if (DetermineDistanceOnStart && ConnectedRigidbody != null)
    Distance = Vector3.Distance(Rigidbody.position, ConnectedRigidbody.position);
    }

    void FixedUpdate()
    {

    var connection = Rigidbody.position - ConnectedRigidbody.position;
    var distanceDiscrepancy = Distance - connection.magnitude;

    Rigidbody.position += distanceDiscrepancy * connection.normalized;

    var velocityTarget = connection + (Rigidbody.velocity + Physics.gravity * Spring);
    var projectOnConnection = Vector3.Project(velocityTarget, connection);
    Rigidbody.velocity = (velocityTarget - projectOnConnection) / (1 + Damper * Time.fixedDeltaTime);


    }
    }
    25 changes: 25 additions & 0 deletions FrictionJoint3D.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class FrictionJoint3D : MonoBehaviour {

    [Range(0,1)]
    public float Friction;

    protected Rigidbody Rigidbody;

    void Awake()
    {
    Rigidbody = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
    Rigidbody.velocity = Rigidbody.velocity * (1 - Friction);
    Rigidbody.angularVelocity = Rigidbody.angularVelocity * (1 - Friction);
    }



    }
    75 changes: 75 additions & 0 deletions RopeRoot.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class RopeRoot : MonoBehaviour {

    public float RigidbodyMass = 1f;
    public float ColliderRadius = 0.1f;
    public float JointSpring = 0.1f;
    public float JointDamper = 5f;
    public Vector3 RotationOffset;
    public Vector3 PositionOffset;

    protected List<Transform> CopySource;
    protected List<Transform> CopyDestination;
    protected static GameObject RigidBodyContainer;

    void Awake()
    {
    if(RigidBodyContainer == null)
    RigidBodyContainer = new GameObject("RopeRigidbodyContainer");

    CopySource = new List<Transform>();
    CopyDestination = new List<Transform>();

    //add children
    AddChildren(transform);
    }

    private void AddChildren(Transform parent)
    {
    for (int i = 0; i < parent.childCount; i++)
    {
    var child = parent.GetChild(i);
    var representative = new GameObject(child.gameObject.name);
    representative.transform.parent = RigidBodyContainer.transform;
    //rigidbody
    var childRigidbody = representative.gameObject.AddComponent<Rigidbody>();
    childRigidbody.useGravity = true;
    childRigidbody.isKinematic = false;
    childRigidbody.freezeRotation = true;
    childRigidbody.mass = RigidbodyMass;

    //collider
    var collider = representative.gameObject.AddComponent<SphereCollider>();
    collider.center = Vector3.zero;
    collider.radius = ColliderRadius;

    //DistanceJoint
    var joint = representative.gameObject.AddComponent<DistanceJoint3D>();
    joint.ConnectedRigidbody = parent;
    joint.DetermineDistanceOnStart = true;
    joint.Spring = JointSpring;
    joint.Damper = JointDamper;
    joint.DetermineDistanceOnStart = false;
    joint.Distance = Vector3.Distance(parent.position, child.position);

    //add copy source
    CopySource.Add(representative.transform);
    CopyDestination.Add(child);

    AddChildren(child);
    }
    }

    public void Update()
    {
    for (int i = 0; i < CopySource.Count; i++)
    {
    CopyDestination[i].position = CopySource[i].position + PositionOffset;
    CopyDestination[i].rotation = CopySource[i].rotation * Quaternion.Euler(RotationOffset);
    }
    }
    }