Why Does My Player Get Launched When Adjusting Weld C0 Position?

I’m currently working on a sitting system in Roblox. Initially, I tried using the HumanoidRootPart (HRP) for seat positioning, but the hitbox became inaccurate — especially when trying to move under low structures, the character would collide incorrectly.

To solve this, I decided to create a separate hitbox system. However, when I use a Weld and change its C0.Position from (0, 0, 0) to something else (like offsetting the seated position), the player suddenly gets launched or flung away.

This is my first time implementing a custom hitbox system, so I’m wondering if I made a fundamental mistake. Am I doing something completely wrong? How should I approach building this kind of system properly?

server Script.(Actually, this script is only related to movement, so it’s not very important.):

local RemoteEvents = script.Parent:WaitForChild("RemoteEvents", 10)
local AnimationFolder = script.Parent:WaitForChild("Animations", 10)
local animationTable = {}

local character = script.Parent.Parent
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:FindFirstChildOfClass("Animator") or humanoid:WaitForChild("Animator")
local isRunning = false
local Crouching = false

for _, anim in pairs(AnimationFolder:GetChildren()) do
	if anim:IsA("Animation") then
		animationTable[anim.Name] = animator:LoadAnimation(anim)
	end
end

local function playsound(object, sound)
	local soundclone = sound:Clone()
	soundclone.Parent = object
	if object.PrimaryPart then
		soundclone.Parent = object.PrimaryPart
	end
	soundclone:Play()
	game:GetService("Debris"):AddItem(soundclone, soundclone.TimeLength + 0.1)
end


RemoteEvents.Run.OnServerEvent:Connect(function(player)
	if player.Character and player.Character == character then
		humanoid.WalkSpeed = 30
		isRunning = true
		if animationTable.Run and not animationTable.Run.IsPlaying then
			animationTable.Run:Play()
			animationTable.Crouch:Stop()
		end
	end
end)

RemoteEvents.Walk.OnServerEvent:Connect(function(player)
	if player.Character and player.Character == character then
		if not Crouching then
			humanoid.WalkSpeed = 18
		end
		isRunning = false
		
		if animationTable.Run and animationTable.Run.IsPlaying then
			animationTable.Run:Stop()
		end
	end
end)

RemoteEvents.Crouch.OnServerEvent:Connect(function(player)
	if player.Character and player.Character == character then
		humanoid.WalkSpeed = 10
		Crouching = true
		if animationTable.Crouch and not animationTable.Crouch.IsPlaying then
			animationTable.Run:Stop()
			animationTable.Crouch:Play()
		end
	end
end)

RemoteEvents.UnCrouch.OnServerEvent:Connect(function(player)
	if player.Character and player.Character == character then
		Crouching = false
		
		if isRunning then 
			humanoid.WalkSpeed = 30
			animationTable.Run:Play()
		elseif not isRunning then
			humanoid.WalkSpeed = 18
		end
		if animationTable.Crouch and animationTable.Crouch.IsPlaying then
			animationTable.Crouch:Stop()
		end
	end
end)


RemoteEvents.Land.OnServerEvent:Connect(function(player)
	if player.Character and player.Character == character then
		playsound(character, script.land)
		animationTable.Land:Play()
	end
end)

another server script:

local Player = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local PhysicsService = game:GetService("PhysicsService")

local function setCollisionGroup(model)
	for _, descendant in model:GetDescendants() do
		if descendant:IsA("BasePart") then
			descendant.CollisionGroup = "PlayerInstance"
		end
	end
end



local function AddWeldToHitbox(character)
local weld = Instance.new("Weld")
	weld.Part0 = character:WaitForChild("Hitbox")
	weld.Part1 = character:FindFirstChild("HumanoidRootPart")
	weld.Parent = character:FindFirstChild("Hitbox")
	character:FindFirstChild("HumanoidRootPart").CanCollide = false
end


Player.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		setCollisionGroup(character)
		AddWeldToHitbox(character)
	end)
end)

local script(Actually, this script is just about movement, but it also includes the part where I adjust the hitbox Weld. So, it’s not very important overall, but the hitbox Weld adjustment is included here.)

local UIS = game:GetService("UserInputService")
local RemoteEvents = script.Parent:WaitForChild("RemoteEvents", 10)
local run = false

UIS.InputBegan:Connect(function(input, gameprocessedevent)
if not gameprocessedevent then 
	if input.KeyCode == Enum.KeyCode.LeftShift then	
		run = true
		RemoteEvents.Run:FireServer()
	elseif input.KeyCode== Enum.KeyCode.C then
			game.Players.LocalPlayer.Character.Hitbox.Size = Vector3.new(4.115, 3, 1.511)  
			--game.Players.LocalPlayer.Character.Hitbox.Weld.C1 = CFrame.new(0,-1,0) the test code.
		RemoteEvents.Crouch:FireServer()
			
	end
	
	end
end)

UIS.InputEnded:Connect(function(input, gameprocessedevent)	
	if not gameprocessedevent then 
		if input.KeyCode == Enum.KeyCode.LeftShift then
			run = false
			RemoteEvents.Walk:FireServer()
		elseif input.KeyCode == Enum.KeyCode.C then
			game.Players.LocalPlayer.Character.Hitbox.Size = Vector3.new(4.115, 5.256, 1.511)  		
			--game.Players.LocalPlayer.Character.Hitbox.Weld.C1 = CFrame.new(0,1,0) the test code.
			RemoteEvents.UnCrouch:FireServer()
		end
		end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	if game.Players.LocalPlayer.Character.Humanoid.MoveDirection.Magnitude < 0.1 and run == true then
	RemoteEvents.Walk:FireServer()
	end
end)

game.Players.LocalPlayer.Character.Humanoid.StateChanged:Connect(function(oldState, newState)
	if oldState == Enum.HumanoidStateType.Freefall and newState == Enum.HumanoidStateType.Landed then
		RemoteEvents.Land:FireServer()
	end
end)

another local script(hitbox script. its a local)

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer

print(player)
local character = player.Character or player.CharacterAdded:Wait()
print(character)
local hrp = character:WaitForChild("HumanoidRootPart")


RunService.Heartbeat:Connect(function()
	script.Parent.CFrame = hrp.CFrame * CFrame.new(0, 0, 0)
end)
1 Like

Please format the code correctly in your post, it is super difficult for anyone to help when it’s not formatted correctly.
Use 3 backticks, new line 3 more backticks

2 Likes

Sorry, my bad. I’ve formatted my code correctly now.

Unsure what exactly you are trying to achieve, but make sure the part that is welded to the character has CanCollide turned off and turn on Massless as well for it not affecting the player physics. And you are also for some reason disabling CanCollide on the HRP?

EDIT: Re-read the post. Seems like you want to make a custom collision via this box? Okay then make sure to turn Massless on, turn on HRP CanCollide, and with Collision Groups make sure that the Collision Group of the hitbox part doesn’t collide with the player Collision Group. Make sure that the Part and Player parts have different collision groups. Create a new group for the hitbox if it’s not created and exclude the hitbox from the :GetDescendants for loop you have there.

1 Like

I think I may not have explained my issue clearly enough. First, I’m trying to create a custom collision system for a sitting mechanic by using a separate part as a hitbox. As you suggested, I’ve already set the HumanoidRootPart’s CanCollide to false and enabled Massless as well.

Regarding collision groups, I currently have a group called PlayerInstances, which includes both the hitbox and all the player’s body parts. This collision group is set up so that parts within it don’t collide with each other.

If you need more details, I can provide a video or share the relevant code. Just let me know.

Okay I think you have a bit misunderstood my post, the correct step by step that I’ve tried to say:

  • Collision group for player parts, collision with itself turned off
  • Collision group for custom hitboxes, collision with itself turned on, collision with player parts turned off
  • Set player parts collision only to the parts of the player body, exclude hitbox from the loop
  • Set custom hitbox collision group to the hitbox
  • Don’t turn off collision on humanoid root part

All this is needed so player parts don’t collide with the hitbox part, but hitbox parts collide with each other, as I suspect it might be useful for multiplayer.

I was being totally clueless it was entirely my mistake. I didn’t realize that, since I had already welded the hitbox part, I didn’t need to manually update its position every frame with RunService. I was busy testing multiple systems at once and completely forgot to remove that code. Because of this, the unnecessary RunService code was causing delays between the server and client, which made the hitbox float or freeze in midair.
Thank you so much for pointing out the solution. Your advice will definitely help me as I keep improving my hitbox system!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.