CFrame spinning wheels for vehicles

I wrote this script to make the wheels on a train spin using cframe but I’m a bit lost on how I can make the wheels spin at the correct rotation speed for the speed that the train is doing.

Script
local wheelParts = {}
local descs = script.Parent:GetDescendants()
local train = script.Parent.Centre
local zRot = 0

for i = 1, #descs do
	if descs[i].Name == "Wheel" or descs[i].Name == "Brake" then
		if descs[i]:IsA("Part") or descs[i]:IsA("MeshPart") or descs[i]:IsA("UnionOperation") then
			table.insert(wheelParts,#wheelParts,descs[i])
		end
	end
end




while wait() do
	for i,v in pairs(wheelParts) do
		local speed = train.Velocity.Magnitude
		zRot += 0.5
		v.CFrame = v.CFrame * CFrame.Angles(0,0,math.rad(zRot))
	end	
end

Video of it working:
https://i.gyazo.com/c2a679e4df3026cc27e4facc6beaae84.mp4

Any ideas how I can get them to spin at the speed the train is going? Do I have to work out the circumference of the wheels or something? Thanks

You would first need to find out the wheel’s circumference as so:

local circ = math.pi * wheel.Size.Y

(note that if the size of the wheels are uniform, this only needs to be stored once)

Then, in your “wait()” statement (which I strongly recommend replacing with a RunService:BindToRenderStep or heartbeat event) you would figure out the rotation amount with this calculation:

local zRot = (((newWheelPosition - lastWheelPosition).Magnitude) / circ) * 360;

which you can feed into what you already have:

v.CFrame *= CFrame.Angles(0,0,math.rad(zRot))

And finally, make sure to reassign the lastWheelPosition after you’ve set the CFrame.

Let me know if there are any problems :+1:

1 Like