I want to make a solid-axle suspension system using joints in unity. Is this possible? If you don’t know what a solid-axle is, check out this wiki article: Beam axle - Wikipedia
Thanks in advanced!
I want to make a solid-axle suspension system using joints in unity. Is this possible? If you don’t know what a solid-axle is, check out this wiki article: Beam axle - Wikipedia
Thanks in advanced!
I know this is a REALLY late response, but if OP or anyone else has trouble with different types of suspensions and/or needs solid axle suspension, I’ve created these two scripts that have really great results for both independent and dependent (solid axle) suspension setups.`using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class New_Physics_Wheel : MonoBehaviour
{
[SerializeField] public enum SuspensionType { IndependentSuspension, SolidAxleSuspension };
public SuspensionType suspensionType;
private Rigidbody rb;
public RaycastHit hit;
public float wheelRadius;
public float wheelMass;
public float restLength;
public float springTravel;
public float suspensionStiffness;
public float suspensionDamper;
public bool isGrounded;
public float springForce;
public float springLength;
private float maxLength;
private float minLength;
private float lastLength;
private float springVelocity;
private Vector3 suspensionForce;
private float damperForce;
public Transform solidAxle;
private New_Physics_SolidAxle _solidAxle;
// Start is called before the first frame update
void Awake()
{
rb = transform.root.GetComponent<Rigidbody>();
if (transform.parent == solidAxle)
{
_solidAxle = solidAxle.GetComponent<New_Physics_SolidAxle>();
}
else
{
_solidAxle = null;
}
springLength = restLength;
maxLength = restLength + springTravel;
minLength = restLength - springLength;
}
// Update is called once per frame
void FixedUpdate()
{
if (Physics.Raycast(transform.position, -transform.up, out hit, maxLength + wheelRadius))
{
isGrounded = true;
}
else
{
isGrounded = false;
springLength = maxLength;
}
if (isGrounded)
{
SuspensionForces();
}
}
void SuspensionForces()
{
lastLength = springLength;
springLength = hit.distance - wheelRadius;
springVelocity = (lastLength - springLength) / Time.fixedDeltaTime;
springForce = suspensionStiffness * (restLength - springLength);
damperForce = suspensionDamper * springVelocity;
if (suspensionType == SuspensionType.SolidAxleSuspension)
{
if (transform.parent == solidAxle)
{
if (transform.name == "Wheel_RL")
{
solidAxleSuspensionForce = _solidAxle.solidAxleForce;
}
if (transform.name == "Wheel_RR")
{
solidAxleSuspensionForce = -_solidAxle.solidAxleForce;
}
}
suspensionForce = (springForce + damperForce + solidAxleSuspensionForce) * transform.up;
}
else if (suspensionType == SuspensionType.IndependentSuspension)
{
suspensionForce = (springForce + damperForce) * transform.up;
}
rb.AddForceAtPosition(suspensionForce, hit.point);
}
void LateUpdate()
{
Debug.DrawRay(new Vector3(transform.position.x, transform.position.y - springLength, transform.position.z), new Vector3(0, -wheelRadius, 0), Color.red, 0, false);
springLength = Mathf.Clamp(springLength, minLength, maxLength);
}
}
`
and:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class New_Physics_SolidAxle : MonoBehaviour
{
private New_Physics_Wheel[] wheels;
public float currentSpringDifference;
public AnimationCurve test;
public float solidAxleForce;
// Start is called before the first frame update
void Awake()
{
wheels = GetComponentsInChildren<New_Physics_Wheel>();
}
// Update is called once per frame
void Update()
{
currentSpringDifference = Mathf.Abs(wheels[1].springLength) - Mathf.Abs(wheels[0].springLength);
for (int i = 0; i < wheels.Length; i++)
{
solidAxleForce = test.Evaluate(currentSpringDifference) * wheels*.maxSolidAxleForce;*
}
}
private void LateUpdate()
{
currentSpringDifference = Mathf.Clamp(currentSpringDifference, 0, (wheels[0].restLength + wheels[0].springTravel) - (wheels[0].restLength - wheels[0].springTravel));
}
}
This setup should work with any vehicle with an even number of wheels (excluding 2), as I’ve tried 4, 6, and 8 wheel setups with different suspension types per axle with success. Just place an object in the middle of an axle you wish to convert from independent to solid axle, parent the two wheels on that axle to it, give it the “New_Physics_SolidAxle” script, and make two keyframes in the animation curve, one with a time of whatever the (max spring length - minspring length) value is, and another with the min spring value set as time. Latter should have 1 as the value and the former should have -1. You don’t need to do any of what was just described if you want an independent suspension setup.
Some good settings for the “New_Physics_Wheel” script are:
With a solid Axle suspension setup:
Suspension type: solid axle suspension
wheel radius: whatever the radius of your visual wheels are which you can easily fine tune using the Debug.DrawRay method as a marker
Wheel mass: 15
Rest Length: 0.38
Spring Travel: 0.16
Suspension Stiffness: 30000
Suspension Damper: 5000
Max Solid Axle Force: 50000
Solid Axle: The transform of the object in the middle of the axle
With an independent suspension setup:
Suspension type: independent suspension
wheel radius: whatever the radius of your visual wheels are which you can easily fine tune using the Debug.DrawRay method as a marker
Wheel mass: 15
Rest Length: 0.38
Spring Travel: 0.16
Suspension Stiffness: 30000
Suspension Damper: 5000
Max Solid Axle Force: 0
Solid Axle: none
Hope this helps somebody!