How to bind part to bone?

How can I bind a part/mesh to a bone?

I have a skinned mesh character in my game. I want it to be able to hold objects, but you can’t weld bones in Roblox. How can I make a baseball bat bind to my player’s hand like he is holding it?

I have tried looking around for answers but haven’t found any working ones. I tried using a script to make the baseball bat’s position the same as the bone’s transformedworldcframe but that has a huge delay.
I also of course tried making it as a tool, but it doesn’t work as the player is skinned mesh, not r6 or r15.

1 Like

You can weld the mesh, and there are two methods of doing so.

Welding Directly
This is a much more efficent method because you only have to update it once.

local root_part; --//Part you want to attach
local mesh_part; --//Meshpart bind to mesh

local heartbeat = game:GetService('RunService').Heartbeat;
local weld = Instance.new('Weld') do --//"Do" is for organization
    weld.Part0 = root_part;
    weld.Part1 = mesh_part;
    weld.C0 = root_part.CFrame:Inverse() * mesh_part.CFrame;
end

Welding to the Bone
Welding to the bone requires an event(Heartbeat) which updates every 1/40 second, this is due to the “WorldPosition” property of the bone not detectable through “:GetPropertyChangedSignal(‘WorldPosition’)”. Roblox decided to remove the part position events when reacting to physics because of the amount of updates it uses, which would slow down the physics engine.

local root_part; --//Any part attached to the character (RootPart reccomended)
local mesh_part; --//Part you want to attach
local bone; --//Bone you want it to weld to

local heartbeat = game:GetService('RunService').Heartbeat;
local weld = Instance.new('Weld') do --//"Do" is for organization
    weld.Part0 = root_part;
    weld.Part1 = mesh_part;
end

heartbeat:Connect(function(time)
    --//Runs 40 times a second
    
    weld.C0 = root_part.CFrame:Inverse() * CFrame.new(bone.WorldPosition);
end);

What is Heartbeat?
Heartbeat is an event which fires about 40 times every second, and gives you the exact time it took (should be a number around 1/40) in the parameters: “function(time)”

Using “taks.wait()” instead of "wait()"
Using task.wait() uses the heartbeat event, which waits around 1/40 seconds, and returns the exact time it took. Using task.wait() is faster than using wait() because wait() waits only 1/20 seconds.

3 Likes

Thank you for answering.
It doesn’t seem to work - I get the error ’ Expected BasePart got Bone for Weld:Part1’

local root_part = script.Parent.Parent.Torso

local bone = root_part:FindFirstChild("mixamorig:Hips"):FindFirstChild("mixamorig:Spine"):FindFirstChild("mixamorig:Spine1"):FindFirstChild("mixamorig:Spine2"):FindFirstChild("mixamorig:RightShoulder"):FindFirstChild("mixamorig:RightArm"):FindFirstChild("mixamorig:RightForeArm"):FindFirstChild("mixamorig:RightHand")

local heartbeat = game:GetService('RunService').Heartbeat;
local weld = Instance.new('Weld') do
	weld.Part0 = root_part; 
	weld.Part1 = bone;
end

heartbeat:Connect(function(time)
	weld.C0 = root_part.CFrame:Inverse() * CFrame.new(bone.WorldPosition);
end);

Welds simply don’t seem to allow bones. Any help is appreciated

Whoops, I made a mistake in the code, I fixed it :smiley:

My bad I should’ve noticed that the mesh part wasn’t included in the script haha
Thanks! The weld works really well!

1 Like