Custom Motor6D movement breaks HumanoidRootPart CFrame / Orientation while moving after jumping from a seat

  1. What do you want to achieve?
    To use Motor6D to control where a character is looking and to prevent the HumanoidRootPart from “wiggling” after a character jumps up from a seat.

  2. What is the issue?
    I’m using a local script to set the player’s Neck and Waist Motor6D to look towards the camera. No issues, everything is expected. After jumping up from a seat, the HumanoidRootPart starts also twisting along with the entire body whereas previously it would only face the characters movement direction.

5ppYHmJlgA compressed
6iRgrA2Cj7

  1. What solutions have you tried so far?
  • Disabling all parts that get welded to character
  • Setting all character parts (including and not including HRP) to massless

I’m 99% sure it has something to do with how Roblox welds characters to seats or something with the teleporting / CFraming.
These are not custom seats, they are normal Roblox seats.

Disabling this local script will solve the problem of the HRP wiggling after getting up from a seat.
It’s still work in progress, I know looking forward does the same as looking backwards here. Services is a shortcut for game:GetServices("").


local TwistCharacterModule = {}
local ModuleScripts = game:GetService("ReplicatedStorage").ModuleScripts
local Services = require(ModuleScripts.ServicesModule)

local player = Services.Players.LocalPlayer

local RemoteEvents = Services.ReplicatedStorage.RemoteEvents
local CharacterEvents = RemoteEvents.CharacterEvents
local TwistCharacterRemoteEvent = CharacterEvents.TwistCharacterRemoteEvent

local camera = workspace.CurrentCamera

local character = player.Character
if not character then
player.CharacterAdded:Wait()
end
local humanoid = character:WaitForChild("Humanoid")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local waist = character:WaitForChild("UpperTorso"):WaitForChild("Waist")
local waistC0 = waist.C0
local neck = character:WaitForChild("Head"):WaitForChild("Neck")
local neckC0 = neck.C0

local twistCharacterSettings = {
	twistRange = 140 / 180,
	bendRange = 120 / 180,
}

local function UpdateWaist(character)
	--print(waist.C0, neck.C0)
	if not humanoid.SeatPart then
		local lookVector = humanoidRootPart.CFrame:ToObjectSpace(camera.CFrame).lookVector.Unit
		--print(lookVector.X, lookVector.Y, lookVector.Z)
		if lookVector.Z >= 0 then -- looking forward
			waist.C0 = CFrame.new(0, waistC0.Y, 0)
				* CFrame.Angles(
					math.asin(lookVector.Y) * twistCharacterSettings.bendRange / 4, 
					math.asin(lookVector.X) * twistCharacterSettings.twistRange / 4, 
					0)

			neck.C0 = CFrame.new(0, neckC0.Y, 0)
				* CFrame.Angles(
					math.asin(lookVector.Y) * twistCharacterSettings.bendRange, 
					math.asin(lookVector.X) * twistCharacterSettings.twistRange, 
					0)
		else -- looking behind
			waist.C0 =
				CFrame.new(0, waistC0.Y, 0)
				* CFrame.Angles(
					math.asin(lookVector.Y) * twistCharacterSettings.bendRange / 4,
					math.asin(lookVector.X) * twistCharacterSettings.twistRange / 4,
					0)

			neck.C0 =
				CFrame.new(0, neckC0.Y, 0)
				* CFrame.Angles(
					math.asin(lookVector.Y) * twistCharacterSettings.bendRange, 
					math.asin(lookVector.X) * twistCharacterSettings.twistRange, 
					0)
		end
		--]]

	else
		if waist.C0 ~= waistC0 then
			waist.C0 = waistC0
		end
		if neck.C0 ~= neckC0 then
			neck.C0 = neckC0
		end
	end
end

TwistCharacterModule.Hookup = function(character)
	print("twisting time!")
	
	TwistCharacterRemoteEvent.OnClientEvent:Connect(function(player, character, waistC0, neckC0)
		if player ~= Services.Players.LocalPlayer and character and character.Humanoid.Health > 0 then
			local waist = character:WaitForChild("UpperTorso"):WaitForChild("Waist")
			local neck = character:WaitForChild("Head"):WaitForChild("Neck")
			waist.C0 = waistC0
			neck.C0 = neckC0
		end
	end)
	
	local OnRenderStepped = Services.RunService.RenderStepped:Connect(function()
		UpdateWaist(character)
		--TwistCharacterRemoteEvent:FireServer(character, waist.C0, neck.C0)
	end)

	spawn(function()
		while true do
			TwistCharacterRemoteEvent:FireServer(character, waist.C0, neck.C0, humanoidRootPart.CFrame)
			--print(character, waist.C0, neck.C0, humanoidRootPart.CFrame)
			wait(1 / 30)
		end
	end)
end

return TwistCharacterModule

I think the problem is because when you offset the C0s, the physics service needs to resolve the offset by applying force on both parts attached by the Motor6Ds, so both the parts will move
you can try to minimize/stop this by setting all parts except the HumanoidRootPart to massless

I will try this out. I’ve attached another gif if it helps diagnosing any further.

It looks like not all my parts were massless. I noticed when spawning in, all character parts are default Massless. At some point, I had another script telling the characters to flip all the parts to have mass. Thanks for your help!

1 Like