How can I improve this velocity calculator?

So I decided it would be neat to have a UI showing how fast you are going constantly (seeing how the project I’m working on is a racing game).

This is the code I wrote up for velocity, and it seems like it could use some improvement, but I’m not really sure what it’s missing. Ideally I would like to run the UpdateVelocity function every frame, but I can’t quite wrap my head around the math I would need to use.

local Core = {Functions = {}, Pathways = {}}
Core.__Index = Core

repeat wait() until game.Players.LocalPlayer.Character

local OldVelocity = Vector3.new(0,0,0)
Core.Pathways.Root = game.Players.LocalPlayer.Character.HumanoidRootPart
Core.Pathways.PGui = game.Players.LocalPlayer.PlayerGui

function Core.Functions.UpdateVelocity(self)
	local NewVelocity = math.ceil((Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z) - OldVelocity).magnitude) * 5
	Core.Pathways.PGui.ScreenGui.TextLabel.Text = ("Velocity: "..NewVelocity)
	OldVelocity = Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z)
end

while wait(.2) do
	Core.Functions:UpdateVelocity()
end
1 Like
function Core.Functions.UpdateVelocity(self)
	Core.Pathways.PGui.ScreenGui.TextLabel.Text = "Velocity: "..Vector3.new(Core.Pathways.Root.Velocity.X, 0, Core.Pathways.Root.Velocity.Z).magnitude
end

while wait(.2) do
	Core.Functions:UpdateVelocity()
end

Using velocity will give a more accurate result since ‘wait(.2)’ will never wait exactly 0.2 seconds

Additionally, I would personally change the wait(.2) to just wait() since just updating a GUIs text every frame is unlikely to have any effects on performance.

wait() won’t update every frame.

If I wanted to run it every frame I would do,

game:GetService("RunService").RenderStepped:Connect(function()
    Core.Functions:UpdateVelocity()
end)

However, if I did that it will return a decimal number nearly every time because of how frequent the update is, which is why I am multiplying NewVelocity by five. Performance isn’t the issue, accuracy is.

1 Like

You need to take the actual wait time into account, since wait(0.2) doesn’t yield the thread for exactly 0.2 seconds.

Perhaps something like this could work:

function Core.Functions.UpdateVelocity(self,delta)
	local NewVelocity = math.ceil((Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z) - OldVelocity).magnitude / delta)
	Core.Pathways.PGui.ScreenGui.TextLabel.Text = ("Velocity: "..NewVelocity)
	OldVelocity = Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z)
end

while true do
	Core.Functions:UpdateVelocity(wait(0.2))
end

Or if you want to run it on RenderStepped:

function Core.Functions.UpdateVelocity(self,delta)
	local NewVelocity = math.ceil((Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z) - OldVelocity).magnitude / delta)
	Core.Pathways.PGui.ScreenGui.TextLabel.Text = ("Velocity: "..NewVelocity)
	OldVelocity = Vector3.new(Core.Pathways.Root.Position.X,0,Core.Pathways.Root.Position.Z)
end

game:GetService("RunService").RenderStepped:Connect(function(delta)
	Core.Functions:UpdateVelocity(delta)
end)

Nevertheless, my point was using Velocity over position will always be more accurate, you can include math.floor(N + 0.5) if you want it to be non decimal

Definitely.

A version that uses the Velocity property could look something like:

function Core.Functions.UpdateVelocity(self)
	Core.Pathways.PGui.ScreenGui.TextLabel.Text = "Velocity: "..math.floor(Vector3.new(Core.Pathways.Root.Velocity.X, 0, Core.Pathways.Root.Velocity.Z).magnitude + 0.5)
end

game:GetService("RunService").RenderStepped:Connect(function()
    Core.Functions:UpdateVelocity()
end)

1 Like

Ah, thanks to you both, I’ve created a version I am happy with using the velocity property now. Thank you very much!

2 Likes

Just letting you two know what this was for! :smiley:

@Coeptus @Zaquille

1 Like

Looking good so far. :+1:t3: