-
-
Save ditzel/ae6ebc115d767da9a5a1e1f70dee27e5 to your computer and use it in GitHub Desktop.
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); | |
} | |
} |
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); | |
} | |
} |
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); | |
} | |
} | |
} |
Hello, I'm pretty sure you just have to reduce proportionally the 'Collider Radius' because you adjusted the scale of entire object, while colliders will spawn with the same radius that probably causing the infinite bouncy effect because they repel each other.
Note : Like blender you can operate calculations directly in Inspector fields ; for example → 1 / 2. In this way you'll be able to keep same behaviors.
Besides I might think it's not a good practice, maybe you could modify the script to adjust automatically with the scale.
Hoping that it helped you. Have a good day
Will this work on iOS and Android mobile devices? thanks
Thank you! One other question: Can the ropes collide with the environment and with each other? And can they be attached to rigid bodies? thanks
How is the "RotationOffset" being calculated? The rope appears as a zig zag without segments being rotated. If the segments are very small the zig zag may be hard to see.
Hello. Where should the three rows be placed ?
Hi, amazing rope made in unity im having abit of issues with the rope once i scale it down to a small scale to use in a plug as a wire the rope just goes mad and rotates like a mad rope. Hopefully you can help and give some pointers
Thank you