using UnityEngine;
namespace GogoGaga.OptimizedRopesAndCables
{
/// <summary>
/// Adds Rigidbody physics interaction to the rope's start and end points.
/// This script should be added to the same GameObject as the Rope component.
/// </summary>
[RequireComponent(typeof(Rope))]
public class RopeRigidbodyInteraction : MonoBehaviour
{
[Header("Rigidbody Interaction Settings")]
[Tooltip("Enable physics interaction for the Start Point handle. The Start Point GameObject must have a Rigidbody component.")]
public bool interactWithStartPoint = false;
[Tooltip("Enable physics interaction for the End Point handle. The End Point GameObject must have a Rigidbody component.")]
public bool interactWithEndPoint = true;
[Header("Physics Control")]
[Tooltip("Controls elasticity. Higher values make the rope more rigid and settle faster, like a steel cable. Lower values make it more elastic.")]
[Range(1f, 50f)]
public float rigidityDamping = 10f;
private Rope rope;
private Rigidbody startPointRb;
private Rigidbody endPointRb;
private void Awake()
{
rope = GetComponent<Rope>();
}
private void Start()
{
// Subscribe to the event to handle runtime changes of rope points
if (rope != null)
{
rope.OnPointsChanged += UpdateRigidbodyReferences;
}
// Perform an initial update of the Rigidbody references
UpdateRigidbodyReferences();
}
private void OnDestroy()
{
// Unsubscribe from the event when the object is destroyed to prevent memory leaks
if (rope != null)
{
rope.OnPointsChanged -= UpdateRigidbodyReferences;
}
}
/// <summary>
/// This method is called when the rope's start or end points are changed.
/// It updates the references to the Rigidbody components on the new points.
/// </summary>
private void UpdateRigidbodyReferences()
{
startPointRb = (rope.StartPoint != null) ? rope.StartPoint.GetComponent<Rigidbody>() : null;
endPointRb = (rope.EndPoint != null) ? rope.EndPoint.GetComponent<Rigidbody>() : null;
}
private void FixedUpdate()
{
// Ensure the rope and its points are valid before applying physics
if (rope == null || rope.StartPoint == null || rope.EndPoint == null)
{
return;
}
// Apply constraint to the start point if enabled and a Rigidbody is present
if (interactWithStartPoint && startPointRb != null)
{
ApplyRopeConstraint(startPointRb, rope.EndPoint.position);
}
// Apply constraint to the end point if enabled and a Rigidbody is present
if (interactWithEndPoint && endPointRb != null)
{
ApplyRopeConstraint(endPointRb, rope.StartPoint.position);
}
}
/// <summary>
/// Applies a physics force to a Rigidbody to keep it attached to the rope.
/// The force acts as a damped spring, pulling the body back when the rope is stretched
/// and damping the velocity to reduce oscillation.
/// </summary>
/// <param name="rb">The Rigidbody to apply the force to.</param>
/// <param name="otherPointPosition">The position of the other end of the rope, which acts as the anchor.</param>
private void ApplyRopeConstraint(Rigidbody rb, Vector3 otherPointPosition)
{
Vector3 connectionVector = otherPointPosition - rb.position;
float currentDistance = connectionVector.magnitude;
// Only apply a restorative force if the rope is stretched beyond its defined length
if (currentDistance > rope.ropeLength)
{
// --- 1. Spring Force (Restorative) ---
// This force pulls the Rigidbody back towards its maximum allowed distance.
Vector3 pullDirection = connectionVector.normalized;
float displacement = currentDistance - rope.ropeLength;
Vector3 restorativeForce = pullDirection * displacement * rope.stiffness;
// --- 2. Damping Force (Rigidity) ---
// This force opposes the Rigidbody's velocity along the pull direction, reducing oscillation.
// We project the Rigidbody's velocity onto the pull direction to find the speed of the bounce.
float velocityAlongPullDirection = Vector3.Dot(rb.linearVelocity, pullDirection);
// The damping force is opposite to this velocity, scaled by our new damping factor.
Vector3 dampingForce = -pullDirection * velocityAlongPullDirection * rigidityDamping;
// --- 3. Total Force ---
// The final force is the combination of the spring force and the damping force.
Vector3 totalForce = restorativeForce + dampingForce;
// Apply the calculated total force to the Rigidbody.
rb.AddForce(totalForce, ForceMode.Force);
}
}
}
}
Made a script that adds rigidbody physics to the rope's start and end points