Hey there, wondering if someone could help me out here…
So I am attempting to create a keybind system, by that I mean when someone is within 5 studs of a part that is recognized as a part that can be interacted with, a BillboardGui will Adornee to that part. I have a somewhat working system, however it breaks upon use of more than one part within a close proximity. By this I mean that two parts are close together, and both within the distance of each other, I want to choose the closest part to the character.
The BillboardGui Adornee’s itself to the correct part, however you need to be within distance of the previous part for the BillboardGui to become visible, not too sure how to explain here is a GIF to show GIF
If someone could leave some tips, advice or solutions that’d be much appreciated! I know it’s something popular that ‘everyone’ wants to be able to do, I just can’t get over the last hurdle. I will also attach my ROBLOX game so you can download to see all scripts. Roblox Keybind Interaction.rbxl (28.8 KB)
Thanks!
2 Likes
Just me trying to understand what you mean by this. So you are trying to get it to only show up when you’re a certain distance from the last part?
1 Like
I’ve had similar issues with things like this before, and I found it work by looping through all the billboard guis and doing a simple distance check which stores the one of least distance.
Unfortunately I’m not on my pc at the moment so I can’t look at your code to suggest a more specific fix, but I’ll give it a look when I get home.
Best of luck.
1 Like
I found the issue, just one character in the code needs to be changed! We all make mistakes, but anyways here’s the fix:
Inside your KeybindInteraction
script (located in StarterPlayer > StarterPlayerScripts
) you have used the wrong variable on line 60, where distance1
should be changed to distance2
since you are wanting to check the distance of the currently active part rather than the part you are iterating through.
Here is the fully fixed script if you just want to copy and paste, but i suggest you take a look at the issue to make sense out of it and see where you went wrong (good learning practice).
--[[
KeybindInteraction
JamieWallace_RBLX
]]
-- < Services > --
local RS = game:GetService("ReplicatedStorage")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
-- < RemoteEvents > --
local events = RS.Events
local interactionEvent = events.InteractionEvent
-- < Constants > --
local player = game.Players.LocalPlayer
local interactionValue = player:WaitForChild("InteractionValue")
local playerGui = player:WaitForChild("PlayerGui")
local keybindBillboardGui = playerGui:WaitForChild("KeybindBillboardGui")
local character = player.Character or player.CharacterAdded:Wait()
local interactionParts = workspace:WaitForChild("Interaction Parts")
local universalDistance = 5
-- < Variables > --
local currentInt eraction = nil
-- < AssignGui > --
function assignGui(part)
local textForGui
local objective, key = part:FindFirstChild("Objective"), part:FindFirstChild("Key")
textForGui = "Press "..key.Value.." to "..objective.Value
keybindBillboardGui.KeybindTextLabel.Text = textForGui
keybindBillboardGui.Adornee = part
keybindBillboardGui.Enabled = true
currentInteraction = part
end
-- < UnAssignGui > --
function unassignGui()
keybindBillboardGui.Enabled = false
keybindBillboardGui.Adornee = nil
currentInteraction = nil
end
-- < CheckDistance > --
function checkDistance(part)
if currentInteraction == nil then
if player:DistanceFromCharacter(part.Position) <= universalDistance then
return true, part
elseif player:DistanceFromCharacter(part.Position) > universalDistance then
unassignGui()
end
elseif currentInteraction then
local distance1, distance2
distance1 = player:DistanceFromCharacter(part.Position)
distance2 = player:DistanceFromCharacter(currentInteraction.Position)
if distance1 < distance2 and distance1 <= universalDistance then
return true, part
elseif distance2 > universalDistance then --here is the issue, distance1 was replaced with distance2
unassignGui()
end
end
end
-- < Initiate Check > --
function initiateCheck()
if interactionValue.Value == true then unassignGui() return end
for _,part in pairs(interactionParts:GetChildren()) do
local value, part = checkDistance(part)
if value then
assignGui(part)
end
end
end
-- < Heartbeat > --
RunService.Heartbeat:Connect(initiateCheck)
-- < Input Began > --
deBounce = false
UIS.InputBegan:Connect(function(input, isTyping)
if isTyping or (not currentInteraction) then return end
if deBounce == false then
deBounce = true
local key = currentInteraction.Key.Value
if input.KeyCode == Enum.KeyCode[key] then
interactionEvent:FireServer(currentInteraction)
end
wait(.25)
deBounce = false
end
end)
2 Likes
Aha… that was slightly embarrassing on my half, thanks for your support!
1 Like
All good, I can’t even count how many times I’ve made a mistake like that!
1 Like