How do i make the part goes to the player head position

i coded this script so when i triggered proximityPrompt it will set the part to the player head until i triggered the proximityPrompt again, but instead the part is just does nothing. here is the script:

local DragObject = script.Parent
local Prompt = script.Parent:WaitForChild("ProximityPrompt")

local Players = game:GetService("Players")

Prompt.Triggered:Connect(function(plr)
	local  player = Players:GetPlayerFromCharacter(plr.Parent
		if player then
			local Head = player.Character:FindFirstChild("Head")
			if Head then
				while true do
					wait(0.01)
					DragObject.CFrame = Head.CFrame * CFrame.new(0, 0, -2) * CFrame.Angles(0, math.rad(180), 0)
				end
			end
		end
	)
end)

also uh… i set the player as this


can someone help me again

thanks :D.

this is the 3rd time i make forum

Could you try this

local PlayerService = game:GetService("Players")

local DragObject = script.Parent
local ProximityPrompt = script.Parent:WaitForChild("ProximityPrompt")

local ObjectOnHead = false

ProximityPrompt.Triggered:Connect(function(Player)
	if ObjectOnHead == true then
		ObjectOnHead = false
		return
	end
	
	local Character = Player.Character
	local Head = if Character then Character:FindFirstChild("Head") else nil

	if Character and Head then
		ObjectOnHead = true
		repeat task.wait()
			if DragObject and Head then
				DragObject.CFrame = Head.CFrame * CFrame.new(Vector3.new(0, 0, -2)) * CFrame.Angles(0, math.rad(180), 0)
			end
		until ObjectOnHead == false or Head == nil or DragObject == nil
        ObjectOnHead = false
	end
end)

please format your code next time.


local hello = true

Like this:

```lua

local hello = true

```

1 Like

it work but how do i make it so when i press the proximityPrompt again it will stop goes to the player head position?

i just realized i need a script with client runContext and i recode the code to this


local PlayerService = game:GetService("Players")

local DragObject = script.Parent
local ProximityPrompt = script.Parent:WaitForChild("ProximityPrompt")

local ObjectOnHead = false
local IsGrabbing = false

local Players = PlayerService:GetPlayers()
local player = PlayerService.LocalPlayer

local function Grab(Statement)
	local Head = player.Character.Head
	
	while Statement == true do
		wait(0.01)
		DragObject.CFrame = Head.CFrame * CFrame.new(0, 0, -1.5) * CFrame.Angles(0, math.rad(0), 0)
	end
end

ProximityPrompt.Triggered:Connect(function(Player)
	if IsGrabbing == false then
		DragObject.CanCollide = false
		IsGrabbing = true
		ProximityPrompt.ActionText = "Drop"
		Grab(true)
	else
		DragObject.CanCollide = false
		IsGrabbing = false
		ProximityPrompt.ActionText = "Grab"
		Grab(false)
	end
end)

it was work, but when i click the prompt again it wont stop goes to the player head position like this

can someone help me fix this?

thanks again :D.

i forgot to click it, bruuuuuuuuuuuuuuuuuuuuuuuuuuh D:

Edit: Sorry, just realized what you need help with; my brain’s too fried to process, haha. I’ll still keep this reply if you want to take ideas or a new perspective.


Add a collision check before moving it to the head position; this will prevent the part from moving into buildings or the map, but this is your game and script. Do whatever you want, as you see fit.

Also, filter out rotations and only include positional movements to avoid flickering caused by rotations not being filtered from the final CFrame while moving, as shown in the video above.

I also recommend using lerps (Linear interpolation) to slightly smooth the part movement. It will make it feel more polished and smooth.

That’s all I have. Unfortunately, I’m too tired to go into detail, so I’m just offering suggestions and fixes based on the video you sent.

i did add collision check, and i just recode my script again… and it kinda work, but when i try to drop the part this happens:

the script rn:

local PlayerService = game:GetService("Players")

local DragObject = script.Parent
local ProximityPrompt = script.Parent:WaitForChild("ProximityPrompt")

local ObjectOnHead = false
local IsGrabbing = false

local Players = PlayerService:GetPlayers()
local player = PlayerService.LocalPlayer

local function Grab(Statement)
	local Head = player.Character.Head
	
	while Statement == true do
		wait(0.01)
		DragObject.CFrame = Head.CFrame * CFrame.new(0, 0, -DragObject.PivotOffset.Z) * CFrame.Angles(0, math.rad(0), 0)
		
		if Statement == false then
			DragObject.CFrame = nil
			break
		end
	end
end

ProximityPrompt.Triggered:Connect(function(Player)
	if IsGrabbing == false then
		DragObject.CanCollide = false
		IsGrabbing = true
		ProximityPrompt.ActionText = "Drop"
		Grab(true)
	else
		DragObject.CanCollide = true
		IsGrabbing = false
		ProximityPrompt.ActionText = "Grab"
		Grab(false)
	end
end)

i have 2 option

1, gave up the grabbing mechanic
2. Completely redo it until its work

first you should check for any errors in the studio output
local player = Players:GetPlayerFromCharacter(plr.Parent
the line above will stops teh code from proceeding to the next line since this is a syntax error

while true do
	wait(0.01)
	DragObject.CFrame = Head.CFrame * CFrame.new(0, 0, -2) * CFrame.Angles(0, math.rad(180), 0)
end

instead of this infinite while loop that doesn’t break, use Renderstepped with connection variable which you can disconnect

sample code
local dragging = false
local dragConnection

dragging = not dragging
if dragging then
		if DragObject.Anchored then
			DragObject.Anchored = false
		end
		print("Started dragging")
		dragConnection = game:GetService("RunService").RenderStepped:Connect(function()
			if head then
				DragObject.CFrame = head.CFrame * CFrame.new(0, 0, -2) * CFrame.Angles(0, math.rad(180), 0)
			end
		end)
	else
		print("Stopped dragging")
		if dragConnection then
			dragConnection:Disconnect()
			dragConnection = nil
		end
	end

or a repeat while loop

sample code
dragging = not dragging

repeat
	task.wait(0.01)
	if head then
		DragObject.CFrame = head.CFrame * CFrame.new(0, 0, -2) * CFrame.Angles(0, math.rad(180), 0)
	end
until not dragging

The most efficient way is to weld the model’s primaryPart/part above the player’s head and unweld it depeding on circumstances; but the model/parts had to be unanchored

@cocoadli109

module
-- DragHelper Module
local RunService = game:GetService("RunService")

local DragHelper = {}


DragHelper.Offset = Vector3.new(0, 5, 0)

-- Internal state
local activeRenderLoop = nil
local isRepeating = false
local currentWeld = nil

local originalPositions = {}  -- Stores dragObject → CFrame

function DragHelper.StopAll()
	DragHelper.StopRenderStep()
	DragHelper.StopRepeat()
	DragHelper.Unweld()
end


-- Save original position
local function storeOriginal(dragObject)
	if dragObject:IsA("Model") then
		originalPositions[dragObject] = dragObject:GetPivot()
	elseif dragObject:IsA("BasePart") then
		originalPositions[dragObject] = dragObject.CFrame
	end
end

-- Public method to restore original CFrame
function DragHelper.ReturnToOriginalPosition(dragObject)
	local saved = originalPositions[dragObject]
	if saved then
		if dragObject:IsA("Model") then
			dragObject:PivotTo(saved)
		elseif dragObject:IsA("BasePart") then
			dragObject.CFrame = saved
		end
	else
		warn("No saved position for dragObject")
	end
end


-- Get the correct attachment part
local function getPrimary(dragObject)
	if dragObject:IsA("Model") then
		-- Wait for PrimaryPart to be set
		local timeout = 5
		local startTime = tick()

		while not dragObject.PrimaryPart and tick() - startTime < timeout do
			task.wait()
		end

		if not dragObject.PrimaryPart then
			warn("Model has no PrimaryPart after waiting!")
			return nil
		end

		return dragObject.PrimaryPart

	elseif dragObject:IsA("BasePart") then
		return dragObject

	else
		warn("Invalid drag object type.")
		return nil
	end
end


-- Apply position safely (works for both Model and Part)
local function applyCFrame(dragObject, targetCFrame)
	if dragObject:IsA("Model") then
		dragObject:PivotTo(targetCFrame)
	elseif dragObject:IsA("BasePart") then
		dragObject.CFrame = targetCFrame
	end
end

-- Method 1: Weld
function DragHelper.WeldToHead(dragObject, head)
	if currentWeld then currentWeld:Destroy() end

	local part = getPrimary(dragObject)
	if not part or not head then return end

	-- Move above head
	local targetCFrame = head.CFrame * CFrame.new(DragHelper.Offset)
	applyCFrame(dragObject, targetCFrame)

	-- Unanchor parts
	if dragObject:IsA("Model") then
		for _, p in ipairs(dragObject:GetDescendants()) do
			if p:IsA("BasePart") then
				p.Anchored = false
			end
		end
	else
		dragObject.Anchored = false
	end

	-- Weld
	local weld = Instance.new("WeldConstraint")
	weld.Part0 = head
	weld.Part1 = part
	weld.Parent = part
	currentWeld = weld
end

function DragHelper.Unweld()
	if currentWeld then
		currentWeld:Destroy()
		currentWeld = nil
	end
end

-- Method 2: Repeat Until
function DragHelper.RepeatDrag(dragObject, head, stopFlagFn)
	isRepeating = true

	local part = getPrimary(dragObject)
	if not part or not head then return end

	task.spawn(function()
		repeat
			task.wait(0.01)
			local targetCFrame = head.CFrame * CFrame.new(DragHelper.Offset)
			applyCFrame(dragObject, targetCFrame)
		until stopFlagFn and stopFlagFn() or not isRepeating
	end)
end

function DragHelper.StopRepeat()
	isRepeating = false
end

-- Method 3: RenderStepped
function DragHelper.RenderStepDrag(dragObject, head)
	local part = getPrimary(dragObject)
	if not part or not head then return end

	if activeRenderLoop then
		activeRenderLoop:Disconnect()
		activeRenderLoop = nil
	end

	activeRenderLoop = RunService.RenderStepped:Connect(function()
		local targetCFrame = head.CFrame * CFrame.new(DragHelper.Offset)
		applyCFrame(dragObject, targetCFrame)
	end)
end

function DragHelper.StopRenderStep()
	if activeRenderLoop then
		activeRenderLoop:Disconnect()
		activeRenderLoop = nil
	end
end

return DragHelper
usage code
--local script
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DragHelper = require(ReplicatedStorage:WaitForChild("DragHelper"))

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")

local partToDrag = workspace:WaitForChild("Rig")--set your model/part

DragHelper.RenderStepDrag(partToDrag,head)

task.delay(5, function()
	DragHelper.StopRenderStep()
end)


--[[use drepeatDrag]]
--local shouldStop = false

---- Start dragging above the head
--DragHelper.StopAll() -- Optional, clears other drag modes
--DragHelper.RepeatDrag(partToDrag, head, function()
--	return shouldStop
--end)

---- ⏱️ Stop after 5 seconds:
--task.delay(5, function()
--	shouldStop = true
--end)

--[[use weld drag]]
--DragHelper.WeldToHead(partToDrag, head)

---- ⏱️ Unweld after 5 seconds
--task.delay(5, function()
--	DragHelper.Unweld()
--end)