Looting script doesn't work, most likely due to wrong location

Hello forum, today i have a very important update which i wanted to publish to my game very recently. It’s a looting system which everytime you look at a model (the script refer to as a lootable object), it’ll check if that model has a loot folder inside of it, if yes then it’ll check and get tool instances inside the folder and get all their info (imageid, name, etc) and put them into a sample frame. The remaining is just the taking system which you right click to show the context menu and 2 button to take it. However, i can’t this to work for some reason. There’s no error, i don’t know why it doesn’t work but i think there’s something with the script when its in a gui. Here’s the script with info

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local items = {}
local buttons = {}
local contextMenuFrame = script.Parent.ContextMenu
local takeButton = contextMenuFrame.Take
local takeAndEquipButton = contextMenuFrame.TakeAndEquip

local userInputService = game:GetService("UserInputService")
local range = 10 -- The range within which to detect lootable objects

local selectedTool = nil
local equippedTool = nil
local takeButtonConnection
local takeAndEquipButtonConnection
local outsideClickConnection

game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)

function waitForCharacterPart(partName)
	local part = character:FindFirstChild(partName)
	while not part do
		part = character:WaitForChild(partName)
	end
	return part
end

function getCharacterPosition()
	local hrp = character:FindFirstChild("HumanoidRootPart") or waitForCharacterPart("HumanoidRootPart")
	return hrp.Position
end

function highlightModel(model, highlight)
	for _, part in ipairs(model:GetChildren()) do
		if part:IsA("BasePart") then
			if highlight then
				if not part:FindFirstChild("Hightlight") then
					local highlight = Instance.new("Highlight")
					highlight.Name = "Highlight"
					highlight.FillColor = Color3.fromRGB(255, 85, 0)
					highlight.OutlineColor = Color3.fromRGB(255, 255, 255)
					highlight.Parent = model
				end
			else
				local highlight = part:FindFirstChild("Highlight")
				if highlight then
				end
			end
		end
	end
end

function detectLootableObjects()
	items = {}
	local characterPosition = getCharacterPosition()
	local hrp = waitForCharacterPart("HumanoidRootPart")
	local characterLookVector = hrp.CFrame.LookVector

	for _, model in pairs(workspace:GetChildren()) do
		if model:IsA("Model") and not model:FindFirstChildOfClass("Humanoid") then -- Ignore player characters
			local lootFolder = model:FindFirstChild("Loot")
			local primaryPart = model.PrimaryPart or model:FindFirstChildOfClass("BasePart")
			if lootFolder and primaryPart and (primaryPart.Position - characterPosition).Magnitude <= range then
				local directionToModel = (primaryPart.Position - hrp.Position).Unit
				local dotProduct = directionToModel:Dot(characterLookVector)

				if dotProduct > 0.5 then -- Adjust the threshold as needed
					highlightModel(model, true)
					for _, tool in pairs(lootFolder:GetChildren()) do
						if tool:IsA("Tool") then
							table.insert(items, tool)
						end
					end
				else
					highlightModel(model, false)
				end
			else
				highlightModel(model, false)
			end
		end
	end
end

function refresh()
	for _, button in pairs(buttons) do
		button:Destroy()
	end
	buttons = {}
	for i, tool in pairs(items) do
		local frame = script.Sample:Clone()
		frame.TextLabel.Text = tool.Name
		frame.LayoutOrder = i
		frame.Parent = script.Parent.Handler
		frame.ImageLabel.Image = tool.TextureId
		table.insert(buttons, frame)
		frame.Hitbox.MouseButton2Click:Connect(function()
			showContextMenu(frame, tool)
		end)
	end
end

function showContextMenu(frame, tool)
	selectedTool = tool
	contextMenuFrame.Visible = true
	contextMenuFrame.Position = UDim2.new(0, frame.AbsolutePosition.X, 0, frame.AbsolutePosition.Y + frame.AbsoluteSize.Y)
	contextMenuFrame.ToolName.Text = frame.TextLabel.Text

	-- Disconnect previous connections to avoid duplicate connections
	if takeButtonConnection then
		takeButtonConnection:Disconnect()
	end
	if takeAndEquipButtonConnection then
		takeAndEquipButtonConnection:Disconnect()
	end
	if outsideClickConnection then
		outsideClickConnection:Disconnect()
	end

	-- Connect the Take button action
	takeButtonConnection = takeButton.MouseButton1Click:Connect(function()
		tool.Parent = player.Backpack
		frame.Visible = false
		contextMenuFrame.Visible = false
		refresh()
	end)

	-- Connect the Take and Equip button action
	takeAndEquipButtonConnection = takeAndEquipButton.MouseButton1Click:Connect(function()
		if equippedTool then
			equippedTool.Parent = player.Backpack
		end
		tool.Parent = character
		equippedTool = tool
		frame.Visible = false
		contextMenuFrame.Visible = false
		refresh()
	end)

	-- Hide context menu when clicking outside
	local function onClickOutside(input)
		if not contextMenuFrame.Visible then return end
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType.Touch then
			local x, y = input.Position.X, input.Position.Y
			local minX, minY = contextMenuFrame.AbsolutePosition.X, contextMenuFrame.AbsolutePosition.Y
			if x < minX or x > minX + contextMenuFrame.AbsoluteSize.X or y < minY or y > minY + contextMenuFrame.AbsoluteSize.Y then
				contextMenuFrame.Visible = false
			end
		end
	end

	-- Connect the click outside event
	outsideClickConnection = userInputService.InputBegan:Connect(onClickOutside)
end

function refreshUI()
	detectLootableObjects()
	refresh()
end

-- Refresh the UI initially and set up a loop to refresh periodically
refreshUI()
game:GetService("RunService").Stepped:Connect(refreshUI)

Here’s the script location:

Screenshot 2024-07-19 194855

Any helps that can fix this problem is highly appreciated!

1 Like

Use the RobloxAPI to handle cases involving loot.

RobloxAPI:OrganizeLoot(GameID)

1 Like

How can i do that? i’ve never heard about robloxapi before

This isn’t a complete solution, however if you want to try debug yourself, try adding print statements around your script to see where things fail at.

Yes, so it did the debugging method you said. Print every functions. However, at the highlight part, it didn’t highlight the model. And it failed to copy a frame into the handler