Problems with SpringConstraint property calculations

Heyoo! Here I am again with a question.

The problem I’m having is the following: I want to do a SpringConstraint property calculation but it’s not working. What am I doing wrong?

local Constraints = {}

for _, Prefix in pairs({"A", "C", "S"}) do
    Constraints[Prefix] = {}

    for _, Position in pairs({"FL", "FR", "RL", "RR"}) do
        local Name = Prefix..Position
        Constraints[Prefix][Position] = Platform:FindFirstChild(Name)
    end
end

local function getSpringForce()
    local springConstraint = Constraints["S"]
    
    local currentLength = springConstraint.CurrentLength
    local freeLength = springConstraint.FreeLength
    
    if (springConstraint.LimitsEnabled) then
        currentLength = math.clamp(currentLength, springConstraint.MinLength, springConstraint.MaxLength)
        freeLength = math.clamp(freeLength, springConstraint.MinLength, springConstraint.MaxLength)
    end
    
    local springLength = currentLength - freeLength -- this is line 110.
    local axis = springConstraint.Attachment0.WorldPosition - springConstraint.Attachment1.WorldPosition
    
    if axis.Magnitude > 0 then
        axis = axis.Unit
    end
    
    local effectiveVelocity = springConstraint.Attachment0.Parent.Velocity - springConstraint.Attachment1.Parent.Velocity
    
    local forceExternal = Vector3.new(0, -(workspace.Gravity + Chassis.Mass:GetMass()), 0)
    local force = springConstraint.Stiffness * springLength - springConstraint.Damping * axis:Dot(effectiveVelocity) + axis:Dot(forceExternal)

    force = math.clamp(force, -springConstraint.MaxForce, springConstraint.MaxForce)
    return force
end

getSpringForce()

Error: Workspace.CarModel.Chassis.Server:110: attempt to perform arithmetic (sub) on nil - Server - Server:110

If you know how to fix it, or if you know of a more effective way to do it, please let me know.

1 Like

Could you show us which line exactly is the problem? (Which line gives the error).

Edit: Nevermind I see the line.

I suggest before running this line, print the currentLength and freeLength. See what it gives you.

1 Like

Both returned nil. What do I do?

Try printing again before

See what it gives you. If it gives you values then it has something to do with this piece of code.

1 Like

I didn’t understand what value is supposed to print.

Did it print anything when u printed currentLength and freeLength before you math.clamp them?

1 Like

Both values returned nil again.

Hmm. It has something to do with what your setting this to. Maybe try doing this:

local function getSpringForce(springConstraint)
    
    local currentLength = springConstraint.CurrentLength
    local freeLength = springConstraint.FreeLength
    
    if (springConstraint.LimitsEnabled) then
        currentLength = math.clamp(currentLength, springConstraint.MinLength, springConstraint.MaxLength)
        freeLength = math.clamp(freeLength, springConstraint.MinLength, springConstraint.MaxLength)
    end
    
    local springLength = currentLength - freeLength -- this is line 110.
    local axis = springConstraint.Attachment0.WorldPosition - springConstraint.Attachment1.WorldPosition
    
    if axis.Magnitude > 0 then
        axis = axis.Unit
    end
    
    local effectiveVelocity = springConstraint.Attachment0.Parent.Velocity - springConstraint.Attachment1.Parent.Velocity
    
    local forceExternal = Vector3.new(0, -(workspace.Gravity + Chassis.Mass:GetMass()), 0)
    local force = springConstraint.Stiffness * springLength - springConstraint.Damping * axis:Dot(effectiveVelocity) + axis:Dot(forceExternal)

    force = math.clamp(force, -springConstraint.MaxForce, springConstraint.MaxForce)
    return force
end

getSpringForce(Constraints["S"])

Does it make a difference?

1 Like

It didn’t make any difference. The error remains the same.

Print springConstraint. If it prints nil then maybe try doing this:

local Constraints = {}
local constraintCheck

for _, Prefix in pairs({"A", "C", "S"}) do
    Constraints[Prefix] = {}

    for _, Position in pairs({"FL", "FR", "RL", "RR"}) do
        local Name = Prefix..Position
        Constraints[Prefix][Position] = Platform:FindFirstChild(Name)
        if Prefix == "S" then
            constraintCheck = Constraints[Prefix][Position]
        end
    end
end

local function getSpringForce(springConstraint)
    local currentLength = springConstraint.CurrentLength
    local freeLength = springConstraint.FreeLength
    
    if (springConstraint.LimitsEnabled) then
        currentLength = math.clamp(currentLength, springConstraint.MinLength, springConstraint.MaxLength)
        freeLength = math.clamp(freeLength, springConstraint.MinLength, springConstraint.MaxLength)
    end
    
    local springLength = currentLength - freeLength -- this is line 110.
    local axis = springConstraint.Attachment0.WorldPosition - springConstraint.Attachment1.WorldPosition
    
    if axis.Magnitude > 0 then
        axis = axis.Unit
    end
    
    local effectiveVelocity = springConstraint.Attachment0.Parent.Velocity - springConstraint.Attachment1.Parent.Velocity
    
    local forceExternal = Vector3.new(0, -(workspace.Gravity + Chassis.Mass:GetMass()), 0)
    local force = springConstraint.Stiffness * springLength - springConstraint.Damping * axis:Dot(effectiveVelocity) + axis:Dot(forceExternal)

    force = math.clamp(force, -springConstraint.MaxForce, springConstraint.MaxForce)
    return force
end

getSpringForce(constraintCheck)
1 Like

Also which positions do you want to getSpringForce. Since what you wrote only contains one value "S"

1 Like

It didn’t change any of the properties, but it didn’t give any error.

image
Sorry for the delay too

The positions are FL, FR, RL, RR.

F - front
R - rear
L - left
R - right

So you want to change it for all four positions from my understanding?

Then do this:

local Constraints = {}
local constraintCheck

local function getSpringForce(springConstraint)
    local currentLength = springConstraint.CurrentLength
    local freeLength = springConstraint.FreeLength
    
    if (springConstraint.LimitsEnabled) then
        currentLength = math.clamp(currentLength, springConstraint.MinLength, springConstraint.MaxLength)
        freeLength = math.clamp(freeLength, springConstraint.MinLength, springConstraint.MaxLength)
    end
    
    local springLength = currentLength - freeLength -- this is line 110.
    local axis = springConstraint.Attachment0.WorldPosition - springConstraint.Attachment1.WorldPosition
    
    if axis.Magnitude > 0 then
        axis = axis.Unit
    end
    
    local effectiveVelocity = springConstraint.Attachment0.Parent.Velocity - springConstraint.Attachment1.Parent.Velocity
    
    local forceExternal = Vector3.new(0, -(workspace.Gravity + Chassis.Mass:GetMass()), 0)
    local force = springConstraint.Stiffness * springLength - springConstraint.Damping * axis:Dot(effectiveVelocity) + axis:Dot(forceExternal)

    force = math.clamp(force, -springConstraint.MaxForce, springConstraint.MaxForce)
    return force
end

for _, Prefix in pairs({"A", "C", "S"}) do
    Constraints[Prefix] = {}

    for _, Position in pairs({"FL", "FR", "RL", "RR"}) do
        local Name = Prefix..Position
        Constraints[Prefix][Position] = Platform:FindFirstChild(Name)
        if Prefix == "S" then
            constraintCheck = Constraints[Prefix][Position]
            getSpringForce(constraintCheck)
        end
    end
end

Edit: Also print and currentLength and freeLength. Does it print nil then?

1 Like

For currentLength it was 2, for freeLength it was 2.5, but something is wrong because the values do not change.

Can you add me on Discord? I think it’s easier to talk there.

If yes, dogusrui#6976

Ok so then I fixed the issues where they used to print nil. I think the values do not change because you are doing math.clamp for them. Since both values are in between the minLength and MaxLength, they will not change. What do you want these values to change to exactly anyway?

I want stiffness and damper to change to make the suspension stable.

Here’s an excerpt of what I’m talking about:
robloxapp-20220424-2017569.wmv (1.9 MB)

So why don’t you change the values straight up? Like do you want it to be changed a certain way or? Because what I see here:

This line of code does not make a difference because as I saw before the image shows that the maxLength is 3 and MinLength is 1.

And these are the values you used to math.clamp. It will not make a difference because non of the values are greater or smaller than the Min or Max Lengths.

Same with here except you are essentially giving back the exact same value because both min and max values are MaxForce which you set to inf.

Edit: If you don’t understand what Math.clamp is then refer to this topic here:

This is why nothing is changing.

Also, it doesn’t seem like you assigned the value force to anything. You just returned it. So that’s just another reason.