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)