Make Player Can't Press E And see GUI when in front of a wall

So I am trying to make an interaction system where you cannot see the GUI or press “E” if you are facing a wall Like Line of sight, I have tried using Raycast but it has not turned out well, what should I do?

Some Info:

You need to be 20 studs near

It works in Any wall


Note : No, i dont want proximityprompt

The current Script:

wait(0.1)
local uis = game:GetService("UserInputService")
local Serverwerkspace = workspace
local camera = game:GetService("Workspace").CurrentCamera
local board = script:WaitForChild("InteractionGui")
local ts = game:GetService("TweenService")

local player = game.Players.LocalPlayer
local character = player.Character
wait()
local rootpart = character:WaitForChild("HumanoidRootPart")
local ShowCooldown = false
local PressCooldown = false
--local MAX_DISTANCE = 35 

game:GetService("RunService").Stepped:Connect(function()	
	for i, v in pairs(game.Workspace:GetChildren()) do
		if v:IsA("BasePart") then
			if v:FindFirstChild("_Interactable") then
				if v:FindFirstChild("Event") then
				local vector, onScreen = camera:WorldToScreenPoint(v.Position)
				 if (rootpart.Position - v.Position).Magnitude <= 20 and onScreen then
					if not ShowCooldown then
						ShowCooldown = true
					local guiclone = board:Clone()
					guiclone.Parent = v
						-- item is on screen and player is within 20 studs
					end
				else
				   if ShowCooldown then
						if v:FindFirstChild("InteractionGui") then
						 ShowCooldown = false
						 v.InteractionGui:Destroy()
							end
					    end
					end
				end
			end
		end
	end
end)
uis.InputBegan:Connect(function(input, GameProcessed, IsTyping)
	if IsTyping then 
		print("No writing pls.")
		return
	elseif input.KeyCode == Enum.KeyCode.E then
		--game:GetService("RunService").Stepped:Connect(function()	
			--local camCFrame = game:GetService("Workspace").CurrentCamera.CFrame.Position
		for i, v in pairs(game.Workspace:GetChildren()) do
			if v:IsA("BasePart") then
			  if v:FindFirstChild("InteractionGui") then
				if v:FindFirstChild("_Interactable") then
						if v:FindFirstChild("Event") then
							if not PressCooldown then
								PressCooldown = true
								local vector, onScreen = camera:WorldToScreenPoint(v.Position)
								--local myRay = Ray.new(rootpart.Position, v.Position/CFrame)

							if (rootpart.Position - v.Position).Magnitude <= 20 and onScreen then -- camera:WorldToScreenPoint(v.Position)
							--print("You Pressed E")
								local guicloned = v.InteractionGui
								local frame = guicloned.InteractionFrame
								local tweenInfo = TweenInfo.new(0.13, Enum.EasingStyle.Quart, Enum.EasingDirection.InOut, 0, true, 0)
								wait()
								local sizetween = ts:Create(frame, tweenInfo, { Size = UDim2.new(0.25, 25,0.25, 25)})

								sizetween:Play()
								v.Event:FireServer()
								wait(0.2)
								PressCooldown = false
								
									-- item is on screen and player is within 20 studs
							end
						end
					end
			    end
		      end
			end
		end
		--end)
	end
end)

Look up ProximityPrompt | Roblox Creator Documentation and the Proximity Prompts | Roblox Creator Documentation section of the developer.roblox.com site.

There is a property of the ProximityPrompt that is called RequiresLineOfSight so if you check that box it should solve your issue.

Actually, I am not using an proximity prompt

I am so confused about your question. Please provide more information.

Questions:

  1. Is it any wall or a certain wall?

  2. Does it matter which side of the wall the player is facing?

  3. To press E and activate this GUI, do you have to be within some distance of something?

Have you tried it? It sounds like this service was made for your type of situation.

I’ll edit the post to provide it, and yeah, there goes more info

  1. ANY wall

  2. No

  3. Yes, like 20 studs near

Yeah, i kinda tried but it doesnt work.

I don’t know why you don’t want to use ProximityPrompts since it pretty much solves your issue easily.

But if you insist, what you can do is, for each of these objects(lets call them GUI activators), you can find all walls within 20 studs of it. Then when a player presses E you can consider the co-ordinates of the player and the nearest GUI activator in the (X, Z) plane and then check if there exists a wall(this wall will be considered a line in the (X, Z) plane, we won’t worry about the height of it) intersecting the line between them.

Not even this link? Proximity Prompts | Roblox Creator Documentation
It gives pretty much all the info you need plus the script and has a place you can check out with multiple ProximityPrompts and their scripts.

Oh yeah i mean, I already have an custom gui

Yes but the design of the default prompt is bad, thats why i want to make my own

You can do this with ray casting in the direction of the interactable object with the origin that is the camera’s CFrame:

local position = v.Position
local cameraPosition = camera.CFrame.Position
local vector, onScreen = camera:WorldToScreenPoint(position)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {game:GetService('Players').LocalPlayer.Character}
-- explanation of the next line, cameraPosition is the position of the camera which is the origin,
-- direction = goal - origin which is how we are getting the direction of the ray
local raycastResult = workspace:Raycast(cameraPosition, position - cameraPosition, raycastParams)
if raycastResult and (v == raycastResult.Instance) and onScreen then
    print('There is no wall blocking the object!')
end
1 Like

Thanks so much, I’l try it and notice you if it worked

1 Like

.It worked Very perfect, Thanks!

1 Like