Hey all! I’m working on a custom spring component (yes, I know there’s a built in spring component, I just thought it would be cool to make my own).
All the issues I’m running into are because I am not the best at physics.
THE ISSUES:
Any physics object attached to my custom spring acts normally at first (and when I say normally, I mean predictably), however, once I start moving any object that the other end of the spring is connected to, my physics object will act sporadically and won’t slow down.
Here’s a demonstration of what I mean:
I think I maybe messed up Hooke’s Law? The resources I looked at were for a singular connection point, while I’m trying to make one object be suspended my multiple springs.
My end goal is to hopefully be able to use these springs in a softbody simulation, but who knows.
Here is my code (implementation of Hooke’s Law starts at line 44):
System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Spring : MonoBehaviour
{
public List<GameObject> connections;
[SerializeField] float springConstant = 25f;
[SerializeField] float dampingValue = 25f;
Rigidbody self;
Vector3 equalibriumPos;
Vector3 originalPos;
Vector3 averageConnectionPoint;
float originalDist;
private void Start()
{
self = GetComponent<Rigidbody>();
originalPos = transform.position;
foreach (GameObject obj in connections)
{
originalDist += Vector3.Distance(originalPos, obj.transform.position);
}
originalDist = originalDist / connections.Count();
equalibriumPos = originalPos;
}
private void Update()
{
UpdateAverageConnectionPoint();
}
private void FixedUpdate()
{
//EQUATION FOR SPRING: FORCE = -velocity -SPRING CONSTANT * DISTANCE OF OBJ FROM EQUALIBRIUM
equalibriumPos = GetEqualibrium();
float distance = transform.position.y - equalibriumPos.y;
float hooksLawForce = (-dampingValue * self.linearVelocity.magnitude) + (-springConstant * distance);
Vector3 forceDirection = (averageConnectionPoint - transform.position).normalized;
self.AddForce(forceDirection * hooksLawForce);
}
private Vector3 GetEqualibrium()
{
Vector3 direction = transform.position - averageConnectionPoint; //Vector that points from our averagePoint to the position of our object
direction = direction.normalized; //Normalize the vector to only get direction
Vector3 sizedDirection = direction * originalDist;
// GET ENDPOINT OF DIRECTION VECTOR: endpoint = startingPoint + vector;
Vector3 endPoint = averageConnectionPoint + sizedDirection;
return endPoint;
}
private void UpdateAverageConnectionPoint()
{
averageConnectionPoint = Vector3.zero;
foreach (GameObject obj in connections)
{
averageConnectionPoint += obj.transform.position;
}
averageConnectionPoint = averageConnectionPoint / connections.Count();
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(equalibriumPos, 0.25f);
Gizmos.DrawLine(equalibriumPos, averageConnectionPoint);
Gizmos.color = Color.green;
foreach (GameObject obj in connections)
{
Gizmos.DrawLine(obj.transform.position, transform.position);
}
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, equalibriumPos);
Gizmos.DrawSphere(averageConnectionPoint, 0.25f);
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, 0.5f);
}
}
The spring constant I’m using is 50, and the Damping value is 0.25.