How to make a "Find Nearest Button" Tycoon Feature

I don’t know if I need to clarify more, but I have been trying to look for this for a while.

I basically need to figure out how to make a button that when clicked, finds the nearest buyable object in a tycoon. Sort of like this:

image

Unfortunately, no matter what I try, I am failing to find a solution.

This is my script (Pardon me if there are simple mistakes, I started experimenting like mad with the code :sweat_smile:

wait(5)

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChild("HumanoidRootPart")

local Button = Player.PlayerGui.FindGui.FindButton

local CanSearch = false
local Range = 1000
local Target = nil

local Folder = game.Workspace.TycoonModel.Buttons

Button.MouseButton1Click:Connect(function()
	if CanSearch == false then
		
		if Humanoid:FindFirstChild("Beam") then
			Humanoid:FindFirstChild("Beam"):Destroy()
		end
		
		Button.Text = "X"
		for i, v in pairs(Folder:GetChildren()) do
			if v.Price.Value <= Player.leaderstats.Cash.Value then
				if Player:DistanceFromCharacter(v.ButtonPart.Position) <= Range then
					Range = Player:DistanceFromCharacter(v.ButtonPart.Position)
					Target = v
				end
			end
			return Target
		end
		
		if Target then
			if Button.Text == "X" then
				CanSearch = true
				local Attachment0 = Humanoid:FindFirstChild("RootRigAttachment")
				local Attachment1 = Target.ButtonPart.Attachment
				local Beam = script.Beam:Clone()
				Beam.Parent = Humanoid
				Beam.Attachment0 = Attachment0
				Beam.Attachment1 = Attachment1
				Beam.Enabled = true
			end
		end
	elseif CanSearch == true then
		Button.Text = "?"
	end
end)

And here are some screenshots of the layout, so you can understand my code a bit more. :slightly_smiling_face:

image

image

If you need me to clarify any more, just let me know.

Thanks in advance for any replies :slightly_smiling_face:

1 Like

Have all the buttons in a table. Have a var for MinDistance which will be the first button on init. Every 1 sec (or a bit more, so not to overload) run through all of them, checking the distance (magnitude) between the character’s primary part and the button. If the distance of button in MinDistance > current checked button then MinDistance = current button. Once you loop through all buttons adjust the beam to point at MinDistance’s button.

here is a simple script.

local players = game:GetService("Players")
local runService = game:GetService("RunService")

local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
character:WaitForChild("HumanoidRootPart")

local tycoonModel = Instance.new("Model") --path to your tycoonModel
local buttons = tycoonModel:WaitForChild("Buttons")

local currentClosestDistance, currentClosestButton = math.huge, nil

runService.RenderStepped:Connect(function()
	for _, v in pairs(buttons:GetChildren()) do
		if (v.ButtonPart.Position - character.PrimaryPart.Position).Magnitude < currentClosestDistance then
			currentClosestButton = v
			print("closest button to "..player.Name.." is: "..v.Name)
		end
	end
end)
1 Like

You can’t use math.abs on a vector3, and also the magnitude of a vector3 will never be a negative number to begin with.

2 Likes

Thank you for telling me. .

Thank you all for your replies! I will try some of these soon and let you know how it went.

Hello everyone,

Sorry for the late reply. I have been experimenting and fixing my script, as well as debugging it. Unfortunately, the i, v in pairs loop only prints one of the three buttons names that I have, and therefore yields the rest of the loop.

Can anyone tell me my problem here? Here is my script:

wait(5)

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChild("HumanoidRootPart")

local Button = Player.PlayerGui.FindGui.FindButton
local Sound = script.Sound

local CanSearch = false
local Range = 1000
local Target = nil

local Folder = game.Workspace.TycoonModel.Buttons

local Beam = script.Beam:Clone()
Beam.Parent = Humanoid

local NewBeam = Humanoid:FindFirstChild("Beam")

Button.MouseButton1Click:Connect(function()
	
	CanSearch = not CanSearch
	print(CanSearch)
	
	if CanSearch == true then
		for i, v in pairs(Folder:GetChildren()) do
			print(v.Name)
			if v.Price.Value <= Player.leaderstats.Cash.Value then
				if v.ButtonPart.Transparency == 0 then
					if Player:DistanceFromCharacter(v.ButtonPart.Position) <= Range then
						Range = Player:DistanceFromCharacter(v.ButtonPart.Position)
						Target = v.Name
					end
				end
			end
			return Target
		end
		
		print(Target)
		
		if Target then
			Button.Text = "X"
			local Attachment0 = Humanoid:FindFirstChild("RootRigAttachment")
			local Attachment1 = Target.ButtonPart.Attachment
			NewBeam.Attachment0 = Attachment0
			NewBeam.Attachment1 = Attachment1
			NewBeam.Enabled = true
		end
		
	elseif CanSearch == false then
		NewBeam.Enabled = false
		Sound:Play()
		Button.Text = "?"
	end
end)

If you could find the issue, I would really appreciate it. Here is what I want the script to do:

  • When the Button is clicked, it searches for the closest buyable object
  • If one is found, create a beam and attach it to the button from the player
  • If not, play a sound to let the player know
  • Update if the object found gets bought

Right now, it clones the beam successfully into the player and updates the value of CanSearch, but the for i, v in pairs loop is going through one of the objects and then yielding the script. (It does not even find the closest one right now)

Thank you all for your help :slightly_smiling_face:

1 Like