Changing models CFrame not working

I just finished making a complex equipment system for weapons and tools in my game. In a new script I’ve made, it’s supposed to handle adding the actual weapon onto the character model. It works generally okay, but for some reason studio just seems to refuse to add the weapon to the correct CFrame.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ToolModule = require(ReplicatedStorage:WaitForChild("ToolModule"))
local ToolData = ToolModule.getToolData()

local player = game:GetService("Players").LocalPlayer

local function characterToolSetup()
	local PlayerData = ReplicatedStorage.Remotes.GetData:InvokeServer(player)
	local character = player.Character

	for _, object in pairs(character:GetDescendants()) do
		for _, item in pairs(ToolData) do
			if object.Name == item.Name then
				object:Destroy()
			end
		end
		if object.Name == "AttachmentPart" then
			object:Destroy()
		end
	end

	if PlayerData.HotbarTool1 ~= 0 then
		local tool = nil
		for _, item in pairs(ToolData) do
			if item.ToolId == PlayerData.HotbarTool1 then
				tool = item
			end
		end

		if tool then
			local toolModel = tool.Model:clone()
			local toolAttachment = tool.Model.Parent:WaitForChild("AttachmentPart"):clone()
			local toolWeld = Instance.new("Weld")
			local attachmentWeld = Instance.new("Weld")

			toolAttachment.Parent = character
			toolAttachment.CFrame = character:WaitForChild("Torso").CFrame
			attachmentWeld.Parent = character.Torso
			attachmentWeld.Part0 = character.Torso
			attachmentWeld.Part1 = toolAttachment
			toolModel.Parent = toolAttachment
			toolModel:PivotTo(toolAttachment.ToolAttachment.WorldCFrame)
			toolWeld.Parent = toolAttachment
			toolWeld.Part0 = toolAttachment
			toolWeld.Part1 = toolModel:WaitForChild("Handle")
		end
	end
end

characterToolSetup()
player.CharacterAdded:Connect(characterToolSetup)
ReplicatedStorage.Remotes.CharacterToolSetup.OnClientEvent:Connect(characterToolSetup)

The script is supposed to stick the weapon to the same CFrame as the tool attachment on the torso but for some reason it just sticks the weapon into the center of the player’s torso.


How it’s supposed to look ^^^

vs how it actually looks now ^^^ (in my torso)

Anything helps really

try this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ToolModule = require(ReplicatedStorage:WaitForChild("ToolModule"))
local ToolData = ToolModule.getToolData()

local player = game:GetService("Players").LocalPlayer

local function characterToolSetup()
	local PlayerData = ReplicatedStorage.Remotes.GetData:InvokeServer(player)
	local character = player.Character

	for _, object in pairs(character:GetDescendants()) do
		for _, item in pairs(ToolData) do
			if object.Name == item.Name then
				object:Destroy()
			end
		end
		if object.Name == "AttachmentPart" then
			object:Destroy()
		end
	end

	if PlayerData.HotbarTool1 ~= 0 then
		local tool = nil
		for _, item in pairs(ToolData) do
			if item.ToolId == PlayerData.HotbarTool1 then
				tool = item
			end
		end

		if tool then
			local toolModel = tool.Model:Clone()
			local referenceAttachment = tool.Model.Parent:WaitForChild("AttachmentPart"):FindFirstChildOfClass("Attachment")
			local toolAttachment = tool.Model.Parent:WaitForChild("AttachmentPart"):Clone()
			toolAttachment.Parent = character
			toolAttachment.CFrame = character:WaitForChild("Torso").CFrame
			local attachmentWeld = Instance.new("Weld")
			attachmentWeld.Part0 = character.Torso
			attachmentWeld.Part1 = toolAttachment
			attachmentWeld.Parent = toolAttachment
			toolModel.Parent = toolAttachment
			toolModel:PivotTo(toolAttachment.ToolAttachment.WorldCFrame)
			local toolWeld = Instance.new("ManualWeld")
			toolWeld.Part0 = toolAttachment
			toolWeld.Part1 = toolModel:WaitForChild("Handle")
			toolWeld.C0 = toolAttachment.ToolAttachment.CFrame
			toolWeld.C1 = toolModel.Handle:FindFirstChild("HandleAttachment").CFrame
			toolWeld.Parent = toolAttachment
		end
	end
end

characterToolSetup()
player.CharacterAdded:Connect(characterToolSetup)
ReplicatedStorage.Remotes.CharacterToolSetup.OnClientEvent:Connect(characterToolSetup)

ehhh I tried what you suggested but now the knife is in the ground

The problem is the weld. When you create a normal Weld and only set Part0 and Part1, Roblox automatically resets the offset so Part1 snaps to the center of Part0. That’s why your weapon ends up inside the torso even though you pivoted it earlier.
Your PivotTo call runs, but as soon as the weld is created the offset gets recalculated and the model moves.

You need to preserve the offset by setting C0 (or C1) when you create the weld, or just use a WeldConstraint instead so Roblox keeps the current position.
For example, after positioning the model:

local weld = Instance.new(“WeldConstraint”)
weld.Part0 = toolAttachment
weld.Part1 = toolModel.Handle
weld.Parent = toolAttachment

WeldConstraint keeps the current world position instead of snapping the parts together.
Also make sure you pivot after the model is parented to workspace/character, otherwise WorldCFrame values from attachments can be incorrect. Once the model is in the character and pivoted, adding the WeldConstraint will keep it exactly where it should be.

Tool Grip Plugin: Can work possibly

1 Like

i think alignposition should work

1 Like

oh my god thank you so much this was like the smallest issue however it was roadblocking most development and it was soooooo annoying. I never really understood the difference between welds and weldConstraints so thank you also for explaining both.

2 Likes

I know that this post has already been solved, however I have another question that is still somewhat relevant:
What if I want to use a Motor6 so that I can animate a part? How can I script a motor6 to be added without the offset thingy setting the weapon to the center of another part?

1 Like

The snapping only happens because the Motor6D defaults C0 and C1 to identity, which means Roblox aligns both part origins together.

If you calculate the offset first and assign it to C0, the current position is preserved. That prevents the weapon from snapping to the center.

So the flow is basically: place the weapon where you want it, compute the relative CFrame, then create the Motor6D using that offset. Once that’s done, the Motor6D keeps that transform and animations can move it from there without resetting the position.

I can explain It in more detail If needed.

1 Like

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