Why won't this script work?

so I have this local script in playerscripts and it wont work.

local Part = game.Workspace:WaitForChild("Part")

game:GetService("RunService").RenderStepped:Connect(function()
	if (game.Players.LocalPlayer.Character.HumanoidRootPart.Position - Part.Position).Magnitude == 5 then
		plr:GetMouse().KeyDown:Connect(function(K)
			if K == "e" then
				game.StarterGui.GunShop.Enabled = true
			end
		end
	end		
end)

I’m tryna make it so if you get close to a part and click E then a gui enables but nothing works, can anyone edit my script? something.

1 Like

where do you define plr here?

i assume you are defining plr as in the local player

local Part = workspace:WaitForChild("Part")
local RunS = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local plr = game:GetService("Players").LocalPlayer
RunS.RenderStepped:Connect(function()
	if (plr.Character.HumanoidRootPart.Position - Part.Position).Magnitude == 5 then
		plr:GetMouse().KeyDown:Connect(function(K)
			if K == "e" then
				StarterGui.GunShop.Enabled = true
			end
		end
	end		
end)

You defined your UI with game.StarterGui. UIs are cloned to the PlayerGui, they are not in the StarterGui.

Along with what @Angrybirdcharacter and @epochzx have added, I wanted to point out that Mouse.KeyDown() was deprecated in favor of UserInputService. You should probably use either that or ContextActionService for things like this.

Also, instead of checking if Magnitude is equal to 5 you should change your sign to compare whether or not Magnitude is less than or equal to x amount of studs. The chances that they would be exactly 5 studs away are extremely slim.

if (plr.Character.HumanoidRootPart.Position - Part.Position).Magnitude <= 5 then
1 Like

Something to add: Using RenderStepped to update the user’s distance from an object is not good practice because the event will still run even if the user doesn’t move which in turn uses up more resources than you really need. Try to use a .Changed event or something of the sort to update the position

that doesn’t work, it’s saying the ends have errors,

theres a missing bracket with the end here

i fixed it, noo errors at all but when im near the part and I click e nothing happens, my script is local sscript and is in playerscripts

1 Like

also there’s a error.


  00:20:53.371  Players.OozyMage.PlayerScripts.LocalScript:6: attempt to index nil with 'HumanoidRootPart'

line:

if (plr.Character.HumanoidRootPart.Position - Part.Position).Magnitude <= 5 then
1 Like

at this point you need UserInputService

local Part = workspace:WaitForChild("Part")
local RunS = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local plr = game:GetService("Players").LocalPlayer
local UIS = game:GetService("UserInputService")

local function keypress(input,gpe)
  if not gpe then
     if input.KeyCode == Enum.KeyCode.E then 
        StarterGui.GunSop.Enabled = true
     end
  end
end

RunS.RenderStepped:Connect(function()
	if (plr.Character.HumanoidRootPart.Position - Part.Position).Magnitude == 5 then
		UIS.InputBegan:Connect(keypress)
	end		
end)

for the humanoidrootpart error try adding waitforchild

Hiwi!

Well I see many errors in your code and method. First you forgot to close a function. Then its impossible to know if you parented that “plr” var.
Then, expecting to have a distance of exactly 5 is nonsense, maybe using less than 5.
Then, you are trying to Enable a GUI in StarterGui, and during game the GUI’s are in PlayerGui.
Using RenderStepped to bind a function or fire it, while the player is close enoug, could fire that function more than once, so you gotta use some locks, or totally change your approach.

Heres your code, fixed, and its working:
(No matter what, I would not recommend using this method)

-- The Part
local Peach = game.Workspace:WaitForChild("Part")
-- Local Player
local Playa = game.Players.LocalPlayer

-- PlayerGui not StarterGui
local playerGui = Playa:WaitForChild("PlayerGui")
local FunShop = playerGui:WaitForChild("GunShop")

game:GetService("RunService").RenderStepped:Connect(function()
	if Playa:DistanceFromCharacter(Peach.Position) < 8 then
		-- print("close enough") Optional print for you to see when you are less than 8 studs
		Playa:GetMouse().KeyDown:Connect(function(K)
			if K == "e" then
				print("Showing GUI")
				FunShop.Enabled = true
			end
		end)  ---  < You missed this close ()
	end
end)

As many others told you. Use UserInputService or ContextActionService to bind the keys.
I think theres better methods to open a simple shop than using a Render loop to check distance, try using events.

3 Likes

Change game.StarterGui to plr.PlayerGui

There is no need for this function to run every single frame. Also, i recommend you use UserInputService rather than GetMouse(), and GetMouse() is depricated in place for userinput service.

You can use a InputBegan event, and check the KeyCode of it.

Another solution to prevent the function from being fired after any input regardless of the key is to bind it to the key via ContextActionService. This allows the function to be bound to certain keys or input types, and only fire on those key presses, rather than on a general InputBegan function.
ContextActionService | Documentation - Roblox Creator Hub.

this is working thank you! could you also add if you click e by the part and walk far away the gui goes invisible?

I insist on changing your approach. Why not using a click detector? Its simpler.
Anyway. Here’s your code. I changed it a little bit.
It uses ContextActionService now. And I renamed your part to Peach xD… So fix that.
When the player is enough close (10 studs) The action gets binded to the E key. And a lock variable onShop is set to true. While the player stays close the E key toggles the GUI (true/false) When the player leaves away more than 10 studs, the action gets unbinded, onShop to false, and Gui.Enabled to false.

-- Using ContextActionService instead of Key method
local CAS = game:GetService("ContextActionService")

-- I renamed the part to Peach cause yes ¯\_(ツ)_/¯
local Peach = game.Workspace:WaitForChild("Peach")
-- Local Player
local Playa = game.Players.LocalPlayer

-- PlayerGui not StarterGui
local playerGui = Playa:WaitForChild("PlayerGui")
local FunShop = playerGui:WaitForChild("GunShop")

-- A dummy lock to know if player is on shop or not
local onShop = false

-- Function binded with ContextActionService
local function OpenFunShop(actionName, inputState, inputObject)
	if actionName == "FunShop" then
		if inputState == Enum.UserInputState.Begin then
			if inputObject.KeyCode == Enum.KeyCode.E then
				if FunShop.Enabled then
					FunShop.Enabled = false
				else
					FunShop.Enabled = true
				end
			end
		end
	end
end

-- Bind and unbind the Action/Function when player gets close and when player leaves
game:GetService("RunService").RenderStepped:Connect(function()
	if Playa:DistanceFromCharacter(Peach.Position) < 10 then
		print("close enough")
		if not onShop then
			CAS:BindAction("FunShop", OpenFunShop, false, Enum.KeyCode.E)
			onShop = true
		end
	else
		if onShop then
			CAS:UnbindAction("FunShop")
			onShop = false
			FunShop.Enabled = false
		end
	end
end)

We’ll be here for any doubts.

2 Likes