My objects that have proximity prompts in them somehow all refer to the same object (WallFirstAidCase) when they’re next to it, WallFirstAidCase is unironically the only consistent object
i have ZERO clue as to why this is happening and i am extremely confused
some objects seem to be able to refer to themselves, but the crate can’t do it at all and always refers to ‘WallFirstAidCase’
All of the proximity prompts are parented to the proper objects, and the objects are all anchored and welded as needed.
again; ZERO clue why this is happening
local pPromptService = game:GetService("ProximityPromptService")
local cService = game:GetService("CollectionService")
local rStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
-- Player variables;
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
-- Path to events;
local eventsFolder = rStorage:WaitForChild("Events")
local bindableEvents = eventsFolder:WaitForChild("Bindable")
-- Events;
local notification = bindableEvents:WaitForChild("Notification")
-- Path to modules;
local playerScripts = player.PlayerScripts
local settingScripts = playerScripts:WaitForChild('Settings')
local modulesFolder = rStorage:WaitForChild("Modules")
local functionalityModules = modulesFolder:WaitForChild("FunctionalityModules")
local weaponModules = modulesFolder:WaitForChild("WeaponModules")
-- Modules;
local openableStats = require(functionalityModules:WaitForChild("OpenableStats"))
local weaponStats = require(weaponModules:WaitForChild("WeaponStats"))
local playerSettings = require(settingScripts:WaitForChild("UserSettingsModule"))
local visuals = require(script:WaitForChild("Visuals"))
-- Path to elements to clone;
local guiElements = rStorage:WaitForChild("GUIElements")
local gameplayGuiElements = guiElements:WaitForChild("Gameplay")
-- Elements to clone;
local promptToClone = gameplayGuiElements:WaitForChild("Prompt")
-- Values;
local checkInterval = 0.05
local distance = 20
local useKey = playerSettings['Keybinds']['Use']
-- Parameters;
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
-- Helper functions;
local function IsPlayerCloseEnough(promptedPart: BasePart)
local root = character.PrimaryPart
local prompt = promptedPart:FindFirstChildOfClass('ProximityPrompt')
local distance = (promptedPart.Position - root.Position).Magnitude
if distance > prompt.MaxActivationDistance then
print(`Player is too far from prompt, max distance is {prompt.MaxActivationDistance}, actual distance is {distance}`)
return false
else
return true
end
end
local function ClearPrompts()
if not script.Parent:FindFirstChildOfClass('BillboardGui') then return end
local promptsCleared = 0
for _, potentialPrompt: BillboardGui in script.Parent:GetChildren() do
if potentialPrompt:IsA('BillboardGui') then
potentialPrompt:Destroy()
promptsCleared += 1
end
end
for _, taggedInstance in cService:GetTagged('objectHighlight') do
taggedInstance:Destroy()
end
print(`All prompts successfully cleared! There was {promptsCleared} prompt/s.`)
end
local function RaycastFromCharacter()
local origin = character.PrimaryPart.Position
local direction = (mouse.Hit.Position - origin).Unit
local raycast = workspace:Raycast(origin, (direction * distance), raycastParams)
if raycast then
return raycast
end
--print('No hit detected, skipping.')
ClearPrompts()
return nil
end
-- Main functions;
local function SetupPrompt(hitInstance: BasePart, promptInstance: ProximityPrompt)
promptInstance.KeyboardKeyCode = useKey
local fullObject = hitInstance:FindFirstAncestorOfClass('Model') or hitInstance:FindFirstAncestorOfClass('Tool')
local prompt = promptToClone:Clone()
local objectData = weaponStats[fullObject.Name] or openableStats[fullObject.Name]
if script.Parent:FindFirstChildOfClass('BillboardGui') then return end
prompt.Parent = script.Parent
prompt.Adornee = hitInstance
prompt.Name = `{fullObject.Name}Prompt`
--prompt.ExtentsOffset = Vector3.new(0, -3, 0)
visuals.SetObjectAndActionText(prompt, objectData, useKey)
visuals.ToggleStatVisibility(objectData, prompt, useKey)
visuals.HighlightObject(fullObject)
visuals.ChangeBorderColor(objectData.tier or 'NaN', prompt)
task.spawn(function()
while prompt.Enabled do
local raycast = RaycastFromCharacter()
if not raycast then
prompt.Enabled = false
break
end
if not raycast.Instance:FindFirstChildOfClass('ProximityPrompt') then
prompt.Enabled = false
break
end
prompt.Enabled = IsPlayerCloseEnough(hitInstance)
task.wait(checkInterval)
end
ClearPrompts()
end)
end
local function ScanForPrompts()
while task.wait(checkInterval) do
if character.Parent ~= workspace.InGame then
--print(`Character's not in-game, skipping`)
continue
end
if player.CameraMode == Enum.CameraMode.Classic then
--print(`Player's camera mode is classic, skipping`)
ClearPrompts()
continue
end
local raycast = RaycastFromCharacter()
if not raycast then continue end
local hitInstance: BasePart = raycast.Instance
local prompt = hitInstance:FindFirstChildOfClass('ProximityPrompt')
if not prompt then
--print('No proximity prompt found, skipping')
continue
end
if not IsPlayerCloseEnough(hitInstance) then continue end
if prompt.Style == Enum.ProximityPromptStyle.Default then
print(`Default prompt style, skipping {prompt.Parent.Parent.Name}`)
continue
end
SetupPrompt(hitInstance, prompt)
end
end
local function OnPromptTriggered(promptTriggered: ProximityPrompt, playerWhoTriggered: Player)
if playerWhoTriggered ~= player then return end
local object = promptTriggered:FindFirstAncestorOfClass('Model') or promptTriggered:FindFirstAncestorOfClass('Tool')
local objectData = openableStats[object.Name]
print(objectData)
print(object.Name)
if not objectData then return end
local openTime = objectData.openTime
if openTime == 0 then return end
notification:Fire('interaction', 'Opening', openTime)
end
local function OnRespawned(newChar: Model)
character = newChar
raycastParams.FilterDescendantsInstances = {character}
end
-- Runtime;
task.spawn(ScanForPrompts)
pPromptService.PromptTriggered:Connect(OnPromptTriggered)
player.CharacterAdded:Connect(OnRespawned)


