Currently im working on a semi-realistic fighter jet system, and i want to implement G-Force calculation, for g-LOC and maybe even wing tearing.
You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I want a reliable way to calculate G-Forces when doing tight maneuvers with a fighter jet
What is the issue? Include screenshots / videos if possible!
I don’t know if my current G-Force calculation is accurate.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
First i have looked through the DevForum, but i found nothing about G-Forces.
Secondly i followed a Unity3D Tutorial about realistic air physics. I translated the Unity code into Lua, but it didn’t seem to work
Here is my current way of calculating G-Forces (Inside a RunService.Heartbeat)
local lastVelocity = 0
-- RunService.Heartbeat
local acceleration = (script.Parent.Parent.CenterMass.AssemblyLinearVelocity.Magnitude - lastVelocity) / dt
local g = math.floor((acceleration * script.Parent.Parent.CenterMass.AssemblyAngularVelocity.Magnitude)/10)
--I divided it by 10 because if i don't do it, the G-Force unrealisticly high.
lastVelocity = script.Parent.Parent.CenterMass.AssemblyLinearVelocity.Magnitude
The linear acceleration is the g-force at the center of gravity. You just need to divide it by whatever gravity is (Workspace.Gravity) to get the right units. You do not need to include the angular velocity in the calculation, although that would give you a more precise result, the difference will be extremely small.
This is wrong. You’re only calculating the difference in speed, a scalar unit, rather than the difference in velocity, which is a vector unit.
You should rearrange your equation so that getting the magnitude is the last step:
local lastVelocity: Vector3 = Vector3.zero
--RunService.Heartbeat
local vel: Vector3 = script.Parent.Parent.CenterMass.AssemblyLinearVelocity.Magnitude
local dv: Vector3 = (vel - lastVelocity) / dt
local acc: number = dv.Magnitude
lastVelocity = vel
And also, due to small fluctuations and imperfections in the measurements, you should consider using some kind of polling buffer to help smooth out and average out the G-Force readings so it is more consistent
local bufferSize: number = 10 --get the average of the last 10 frames
local record: {Vector3} = table.create(10, Vector3.zero) --this will store the buffer
count = 0
local lastVelocity: Vector3 = Vector3.zero
--RunService.Heartbeat
local vel: Vector3 = script.Parent.Parent.CenterMass.AssemblyLinearVelocity.Magnitude
local dv: Vector3 = (vel - lastVelocity) / dt
count += 1 --constantly cycle through the buffer so that the oldest entries get replaced
record[count] = dv
if count == bufferSize then
count = 0
end
local av: Vector3 = Vector3.zero --this will be the average
for _, entry in record do
av += entry --sum up all the accelerations
end
av /= bufferSize --average them out
acc = av.Magnitude --final answer
lastVelocity = vel
Additional note, I remember testing something in the past where I discovered that using the dt value from RunService.Stepped is more reliable than using the dt value of RenderStepped, but the function itself is still ran by RenderStepped
Something like this:
local dt: number = 0
RunService.Stepped:Connect(function(_, delta)
dt = delta
end)
RunService.RenderStepped:Connect(function()
--use dt from .Stepped here
end)
First of all, thank you so much for this amazing response. Everything was very well explained.
Secondly i think you forgot to divide acc by workspace.Gravity, because i don’t think takeoff would do 150 G’s
My plane pulls around 3 G’s max, but i think its because the max speed is 700 SPS.