How to Rig a Car

Thanks for the awesome tutorial. I had one issue i wanted to ask about. When my car makes a heavy impact the wheels tend to get knocked through the body and inverted. I added a flat part above the platform part and set it to collide with the wheels to limit the upward travel of the wheels. This helped but I still find sometimes my wheels get dislodged and wind up hanging from the springs. Is there something else that is needed to make the wheels more ‘attached’?

1 Like

It might help to add min/max length limits for the cylindrical constraint

1 Like

I think the spherical wheel use may depend on the use of the vehicle. I tried adding spherical wheels to mine and when testing in the Roblox demo racing came, they kept trying to climb over bridge railings and cliff walls where the cylindrical ones would bounce off and keep me on course better.

As for other suggestions, maybe add the collision group creation steps into the script so the vehicle model is more game portable.

Here is the code I added to mine so the script would create the collision groups automatically and assign the parts to them. I put this in the CarHandler script near the beginning just after the Cooldown function:

function getGroupId(name)
	-- GetCollisionGroupId will throw error if it does not exist
	local ok, groupId = pcall(physicsService.GetCollisionGroupId, physicsService, name)
	return ok and groupId or nil
end

local checkforgroup
checkforgroup = getGroupId("Character")
if checkforgroup == nil then physicsService:CreateCollisionGroup("Character") end
checkforgroup = getGroupId("CarBody")
if checkforgroup == nil then physicsService:CreateCollisionGroup("CarBody") end
checkforgroup = getGroupId("CarWheel")
if checkforgroup == nil then physicsService:CreateCollisionGroup("CarWheel") end
physicsService:CollisionGroupSetCollidable("Character", "CarBody", false)
physicsService:CollisionGroupSetCollidable("CarWheel", "CarBody", false)
for _,part in ipairs(script.Parent:GetDescendants()) do
		if (part:IsA("BasePart")) then
			if part.Name == "PhysicalWheel" then physicsService:SetPartCollisionGroup(part, "CarWheel")  end
			if part.Name == "Body" then physicsService:SetPartCollisionGroup(part, "CarBody") end
		end
end

This will allow you to export the model and import it into another game and not have to manually recreate the groups and assign the parts, assuming you labeled the parts exactly the same and the game doesn’t have the groups already in which case you may have some overlap issues. This worked for me.
(edit: I misunderstood how the check function worked, I’ve updated this script clip to work properly now if the group already exists)

Hello, I finished part 3, and it will not let me inside the car for some reason. Can someone help?

local car = script.Parent
local seat = car.Body.VehicleSeat
local body = car.Body.Body

local physicsService = game:GetService("PhysicsService")
local defaultCollisionGroup = "Default"
local characterCollisionGroup = "Character"

local cooldown = 0

local occupiedPlayer

local function Cooldown(duration)
	local cooldownTag = tick()
	cooldown = cooldownTag
	delay(duration, function()
		if (cooldown == cooldownTag) then
			cooldown = 0
		end
	end)
end

local function SetCharacterCollide(character, shouldCollide)
	local group = (shouldCollide and defaultCollisionGroup or characterCollisionGroup)
	for _,part in ipairs(character:GetDescendants()) do
		if (part:IsA("BasePart")) then
			part.Massless = not shouldCollide
			physicsService:SetPartCollisionGroup(part, group)
		end
	end
end

local function BodyTouched(part)
	
	if (seat.Occupant or cooldown ~= 0) then return end
	
	local character = part.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	if (not player) then return end
	
	local humanoid = character:FindFirstChildOfClass("Humaniod")
	if (not humanoid) then return end
	
	
	seat:Sit(humanoid)
	occupiedPlayer = player
	SetCharacterCollide(character, false)
	car.PrimaryPart:SetNetworkOwner(player)
	Cooldown(1)
end

local function OccupantChanged()
	if (seat.Occupant) then return end
	if (occupiedPlayer.Character) then
		SetCharacterCollide(character, false)
	end
	car.PrimaryPart:SetNetworkOwnershipAuto()
	occupiedPlayer = nil
end

body.Touched:Connect(BodyTouched)
seat:GetPropertyChangedSignal("Occupant"):Connect(OccupantChanged)

spelling error? check Humanoid

2 Likes

Thanks, it works now.

I am dumb.

Has anyone noticed lag issues when using this model with a phone or tablet?

It seems to run in slow motion for me on mobile. The speed shown by the default vehicle seat GUI is reaching the limit, but the screen is updated very slowly. As soon as I jump out of the car the screen updating goes back to being quick(normal). I’ve tried several things to see if it made a difference and haven’t found a way to improve performance yet.

Things I’ve tried:
Lowering graphics to the lowest level didn’t help.
I tried using renderstepped,
tried a simple wait loop,
I tried using only a server script.
I tried simplifying a bit by using two motors/wheels.
I tried a custom camera.

Nothing has improved it. I know I’ve used vehicle seats before in mobile games that didn’t cause a slow motion effect, so I don’t think its the vehicleseat and camera causing it. For comparison I tried one of the Roblox example game demo white jeeps and the motion didn’t have the same slowness issues on mobile.

I’m kinda stumped and wondering if anyone else has similar results or knows what could be going on.

1 Like

I think I found the cause of my issue. Apparently not all meshparts are created equal. I had swapped out the tutorial body meshpart for another which was causing more lag for mobile. I figured it out by replacing the body with a single brick part. Performance on mobile was very good. Then I put back the meshpart, slow motion again.

I set the meshpart collision to Box from Hull and that helped quite a bit, but nowhere near the performance of the simple brick part.

Could this tutorial work with creating a motorbike? I’ve tried using the car from the tutorial that works fine for a motorbike but I’m not getting very far.

Edit: I mainly mean how can I stop the bike from falling over?

Use a bodygyro…

I checked out those threads and they are pretty good at explaining how to get the cars RPM. What i’m stuck on is like implementing that sort of system into this car rig. I’ve researched so much about car gear ratios, getting torque, transmission types, etc, but i’m just stumbled on implement it into code :frowning:

1 Like

I have an open-source car chassis that uses crazyman32’s rig, but it also includes a gear system and ackermann steering, and stuff.

13 Likes

WOW That answered all my questions tysm!

1 Like

How did you get the car to steer so smoothly? Mine turns like a flat block of cheese, even after trying to get it looking like yours with like 30 minutes of trying different things

I’m having trouble with using spheres instead of cylinders. I can run the script to move and resize the cylinders over the wheels but when I run it on the sphere it shrinks too much and doesn’t move. Including a picture and the code I typed into the command bar. I’m not sure how to make spheres work? Could someone please help me figure this out?

local first = selection[1]
local last = selection[2]

first.Size = last.Size
first.CFrame = last.CFrame

This is because spheres can only have the same size on each axis. Try making the sphere’s size slightly larger than the size of last.

1 Like

When I changed the sphere’s size to 10, 10, 10 the ran the command it moved it this time but it still shrunk it too much.
image

Try making it bigger…

Ok so I used the command to get it into the correct position then manually resized it to 2.6, 2.6, 2.6

1 Like