Sorry for the really late reply but I think I have just what your looking for. I was able to make the arms point at the attachments you have in the steering wheel. The arms were too short to reach on their own so I made the character lean forward by editing the Waist joint. If you don’t want the character to lean forward and still reach the wheel you will need to adjust your model so that can happen. There is a variable in the code that controls how many degrees forward the character is leaning you can mess with that if you edit the car. If you want to make the turning more dramatic you can edit how much the steering wheel turns in your constraints properties I think, my code should still work with it
The only downside to this code is that the joint movement dont replicate to the server Something I suggest is that when the player gets on the car you could tell the server to get the character into the starting pose so its leaning forward with arms out so its touching the wheel. The actual steering part could be purely client side, if your making some kind of racing game its unlikely any other players will be paying close enough attention to notice that other player’s arms aren’t turning the wheel anyway.
You can copy and paste this into a localscript and this should work, here is my save file too just in case
ChassisSteering.rbxl (68.9 KB)
local plr = game.Players.LocalPlayer
local char = workspace:WaitForChild(plr.Name)
local handLeft = workspace.Chassis.Parts.SteeringWheel.HandLeft
local handRight = workspace.Chassis.Parts.SteeringWheel.HandRight
--These two angles were found by trial and error, adjust if you want
local characterLeanAngle = math.rad(20)--How many degrees the character is leaning forward
local neckAngle = math.rad(-15)--How many degrees the head is looking up/down
local steppedEvent
---Create Welds identical to Motor6Ds to override animations
function configureJointsForSteering()
local rightShoulder = char:WaitForChild("RightUpperArm").RightShoulder
local leftShoulder = char:WaitForChild("LeftUpperArm").LeftShoulder
local rightElbow = char.RightLowerArm.RightElbow
local leftElbow = char.LeftLowerArm.LeftElbow
--Torso Weld is to keep the player leaning forward so the arms reach the steering wheel
local torsoWeld = Instance.new("Weld")
torsoWeld.Part0 = char.UpperTorso.Waist.Part0
torsoWeld.Part1 = char.UpperTorso.Waist.Part1
torsoWeld.C0 = char.UpperTorso.Waist.C0 *CFrame.Angles(-characterLeanAngle, 0, 0)
torsoWeld.C1 = char.UpperTorso.Waist.C1
torsoWeld.Name = "WaistWeld"
torsoWeld.Parent = char.UpperTorso
--Neck weld is to make the player's head look up, since the character is leaning forward the head is naturally looking down, so we need to adjust
local neckWeld = Instance.new("Weld")
neckWeld.Part0 = char.Head.Neck.Part0
neckWeld.Part1 = char.Head.Neck.Part1
neckWeld.C0 = char.Head.Neck.C0 *CFrame.Angles(-neckAngle, 0, 0)
neckWeld.C1 = char.Head.Neck.C1
neckWeld.Name = "NeckWeld"
neckWeld.Parent = char.Head
--Shoulder welds so we can make them move towards the steering wheel
local rightShoulderWeld = Instance.new("Weld")
rightShoulderWeld.Part0 = rightShoulder.Part0
rightShoulderWeld.Part1 = rightShoulder.Part1
rightShoulderWeld.C0 = rightShoulder.C0
rightShoulderWeld.C1 = rightShoulder.C1
rightShoulderWeld.Parent = rightShoulder.Parent
rightShoulderWeld.Name = "RightShoulderWeld"
rightShoulder = rightShoulderWeld
local leftShoulderWeld = Instance.new("Weld")
leftShoulderWeld.Part0 = leftShoulder.Part0
leftShoulderWeld.Part1 = leftShoulder.Part1
leftShoulderWeld.C0 = leftShoulder.C0
leftShoulderWeld.C1 = leftShoulder.C1
leftShoulderWeld.Parent = leftShoulder.Parent
leftShoulderWeld.Name = "LeftShoulderWeld"
leftShoulder = leftShoulderWeld
--Elbow welds to keep the arms straight
rightElbow = Instance.new("Weld")
rightElbow.Part0 = rightShoulder.Part1
rightElbow.Part1 = char.RightLowerArm
rightElbow.C0 = CFrame.new(0, -rightElbow.Part1.Size.Y/2, 0)
rightElbow.Name = "RightElbowWeld"
rightElbow.Parent = char.RightLowerArm
leftElbow = Instance.new("Weld")
leftElbow.Part0 = leftShoulder.Part1
leftElbow.Part1 = char.LeftLowerArm
leftElbow.C0 = CFrame.new(0, -leftElbow.Part1.Size.Y/2, 0)
leftElbow.Name = "LeftElbowWeld"
leftElbow.Parent = char.LeftLowerArm
return rightShoulder, leftShoulder
end
function cleanupJoints()
local waistWeld = char.UpperTorso:FindFirstChild("WaistWeld")
local neckWeld = char.Head:FindFirstChild("NeckWeld")
local rs = char.RightUpperArm:FindFirstChild("RightShoulderWeld")
local ls = char.LeftUpperArm:FindFirstChild("LeftShoulderWeld")
local re = char.RightLowerArm:FindFirstChild("RightElbowWeld")
local le = char.LeftLowerArm:FindFirstChild("LeftElbowWeld")
if waistWeld then
waistWeld:Destroy()
end
if neckWeld then
neckWeld:Destroy()
end
if rs then
rs:Destroy()
end
if ls then
ls:Destroy()
end
if re then
re:Destroy()
end
if le then
le:Destroy()
end
end
function handsOnWheel(rightShoulder, leftShoulder)
--Find the positions on the wheel we want the hand to point to
local rightTargetPosition = CFrame.new(rightShoulder.Part0.CFrame:PointToObjectSpace(handRight.WorldPosition)) *(rightShoulder.C0 - rightShoulder.C0.p)
local leftTargetPosition = CFrame.new(leftShoulder.Part0.CFrame:PointToObjectSpace(handLeft.WorldPosition)) *(leftShoulder.C0 - leftShoulder.C0.p)
--Adjust target positions so that the center of the hand will point to target position, otherwise the top left part of the hand will point to target position
rightTargetPosition = rightTargetPosition *CFrame.new(-rightShoulder.Part1.Size.X/2, -rightShoulder.Part1.Size.Y/2, 0)
leftTargetPosition = leftTargetPosition *CFrame.new(leftShoulder.Part1.Size.X/2, -leftShoulder.Part1.Size.Y/2, 0)
--Rotate arms 90 degrees downward so that the end of the hand will point to target position
local rightC0 = CFrame.new(rightShoulder.C0.p, rightTargetPosition.p) *CFrame.Angles(math.rad(90), 0, 0)
local leftC0 = CFrame.new(leftShoulder.C0.p, leftTargetPosition.p) *CFrame.Angles(math.rad(90), 0, 0)
rightShoulder.C0 = rightC0
leftShoulder.C0 = leftC0
end
--When someone sits in the vehicle seat
workspace.Chassis.VehicleSeat:GetPropertyChangedSignal("Occupant"):Connect(function()
if workspace.Chassis.VehicleSeat.Occupant == char.Humanoid then
local rightShoulder, leftShoulder = configureJointsForSteering()
--Setup event that will move hands to the wheel
steppedEvent = game["Run Service"].RenderStepped:Connect(function()
handsOnWheel(rightShoulder, leftShoulder)
end)
else
cleanupJoints()--Put joints back to normal
if steppedEvent then
steppedEvent:Disconnect()--Stop making the players hands stay on the wheel and stop memory leaks
end
end
end)