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.
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.
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