Pick up dummy system

i have been trying to make a script where if i click on an npc i can kind of pick it up, the script below slightly works, but not well

my problems are that i want it to be physics-based, like ragdoll when picked up, so then i could swing the npc around and throw them or something

and also for some reason it will either work once, twice or none, its so weird idk why it stops working

here is the script:




--[[ 
    Revised NPC Pickup Script with Debounce, Hover Highlight, No Throw Force, and Ragdoll Effect

    Requirements:
      - A RemoteEvent named "SetNetworkOwnershipEvent" in ReplicatedStorage.
      - A TextButton named "PickupButton" as a child of the GUI containing this LocalScript.
      - The NPC models must have a PrimaryPart set and include a Humanoid.
      
    Note: The server must handle the remote event to change network ownership.
--]]

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local runService = game:GetService("RunService")
local userInputService = game:GetService("UserInputService")
local replicatedStorage = game:GetService("ReplicatedStorage")

local setNetworkOwnershipEvent = replicatedStorage:WaitForChild("SetNetworkOwnershipEvent")
local pickupButton = script.Parent:WaitForChild("PickupButton")

local pickupMode = false
local heldNPC = nil
local bodyPos, bodyGyro
local debounce = false  -- Prevent multiple pickups in rapid succession

-- Variables for hover highlighting
local lastHighlightedNPC = nil

-- Function to add a white highlight over an NPC model
local function addHighlight(npcModel)
	if npcModel and not npcModel:FindFirstChildOfClass("Highlight") then
		local hl = Instance.new("Highlight")
		hl.FillColor = Color3.new(1, 1, 1)
		hl.OutlineColor = Color3.new(1, 1, 1)
		hl.FillTransparency = 0.5
		hl.OutlineTransparency = 0
		hl.Parent = npcModel
	end
end

-- Function to remove any highlight from an NPC model
local function removeHighlight(npcModel)
	if npcModel then
		for _, child in ipairs(npcModel:GetChildren()) do
			if child:IsA("Highlight") then
				child:Destroy()
			end
		end
	end
end

-- Function to ragdoll the NPC
local function enableRagdoll(npcModel)
	local humanoid = npcModel:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		humanoid:UnequipTools()
	end
	for _, part in ipairs(npcModel:GetDescendants()) do
		if part:IsA("BasePart") then
			part.Anchored = false
		end
	end
end

-- Function to pick up the NPC
local function pickUpNPC(npcModel)
	if not npcModel or not npcModel.PrimaryPart then
		warn("Invalid NPC model or missing PrimaryPart!")
		debounce = false
		return
	end

	heldNPC = npcModel
	enableRagdoll(npcModel)

	-- Request network ownership change (server-side handling)
	setNetworkOwnershipEvent:FireServer(npcModel)

	local primary = npcModel.PrimaryPart

	-- Create BodyPosition for smooth movement
	bodyPos = Instance.new("BodyPosition")
	bodyPos.MaxForce = Vector3.new(1e5, 1e5, 1e5)
	bodyPos.P = 5000
	bodyPos.D = 2000
	bodyPos.Parent = primary

	-- Create BodyGyro to control rotation
	bodyGyro = Instance.new("BodyGyro")
	bodyGyro.MaxTorque = Vector3.new(1e5, 1e5, 1e5)
	bodyGyro.P = 2500
	bodyGyro.Parent = primary

	print("Picked up NPC: " .. npcModel.Name)
	debounce = false
end

-- Function to release the NPC (simply stops control)
local function releaseNPC()
	if heldNPC and heldNPC.PrimaryPart then
		if bodyPos then bodyPos:Destroy() end
		if bodyGyro then bodyGyro:Destroy() end
		heldNPC = nil
	end
end

-- Toggle pickup mode via the GUI button
pickupButton.MouseButton1Click:Connect(function()
	pickupMode = not pickupMode
	if pickupMode then
		pickupButton.Text = "Pickup Mode: ON"
	else
		pickupButton.Text = "Pickup Mode: OFF"
		releaseNPC()
	end
end)

-- Highlight NPC under the mouse when in pickup mode
mouse.Move:Connect(function()
	if not pickupMode then
		if lastHighlightedNPC then
			removeHighlight(lastHighlightedNPC)
			lastHighlightedNPC = nil
		end
		return
	end

	local target = mouse.Target
	local npcModel = target and target:FindFirstAncestorWhichIsA("Model")
	if npcModel and npcModel:FindFirstChildOfClass("Humanoid") then
		if lastHighlightedNPC and lastHighlightedNPC ~= npcModel then
			removeHighlight(lastHighlightedNPC)
			lastHighlightedNPC = nil
		end
		if not npcModel:FindFirstChildOfClass("Highlight") then
			addHighlight(npcModel)
		end
		lastHighlightedNPC = npcModel
	else
		if lastHighlightedNPC then
			removeHighlight(lastHighlightedNPC)
			lastHighlightedNPC = nil
		end
	end
end)

-- On mouse click, attempt to pick up an NPC if not already holding one and not in debounce
mouse.Button1Down:Connect(function()
	if pickupMode and not heldNPC and not debounce then
		debounce = true
		local target = mouse.Target
		if target then
			local npcModel = target:FindFirstAncestorWhichIsA("Model")
			if npcModel and npcModel:FindFirstChildOfClass("Humanoid") then
				removeHighlight(npcModel)
				pickUpNPC(npcModel)
			else
				print("No valid NPC model found!")
				debounce = false
			end
		else
			print("No target detected!")
			debounce = false
		end
	end
end)

-- Release NPC on mouse button release
userInputService.InputEnded:Connect(function(input)
	if pickupMode and heldNPC and input.UserInputType == Enum.UserInputType.MouseButton1 then
		releaseNPC()
	end
end)

-- Continuously update the held NPC to follow the mouse
runService.RenderStepped:Connect(function()
	if pickupMode and heldNPC and heldNPC.PrimaryPart and bodyPos then
		local hit = mouse.Hit
		if hit then
			local targetPos = hit.Position + Vector3.new(0, 5, 0)
			bodyPos.Position = heldNPC.PrimaryPart.Position:Lerp(targetPos, 0.1)
			if bodyGyro then
				bodyGyro.CFrame = CFrame.new(heldNPC.PrimaryPart.Position, targetPos)
			end
		end
	end
end)










1 Like