ProximityPromt | WorldToScreenPoint() проблема

sq5wik

Member
27 Апр 2025
2
0
1
Решил сделать так чтобы промты показывались в гуи, написал скрипт но почему то сам фрейм показывается совсем не там где надо, как можно решить?
1745745468547.png
Видео вставил, там видно как сам фрейм (в будущем промт) не меняет свою X позицию...
 

Вложения

  • Roblox-2025-04-27T09_18_04.647Z.mp4
    7,4 МБ

mAloy

Member
10 Сен 2025
7
0
1
Здравствуйте. Посмотрел ваш скрипт. Проблема возникает из-за того, как вы обрабатываете координаты для GUI.
Суть проблемы:
Функция WorldToScreenPoint возвращает сразу несколько значений: Vector3 (с координатами X и Y на экране) и флаг, который показывает, виден ли объект. Вы же пытаетесь получить X и Y по отдельности и используете их некорректно, что приводит к ошибке в позиционировании.
Решение:
Нужно получить экранные координаты одним вызовом и затем использовать их для установки позиции фрейма.
Вот исправленная функция PositionPrompt, которая решает эту задачу:
-- Эта функция будет двигать наш фрейм по экрану
function PositionPrompt(promptObject)
-- Сначала надо понять, где вообще находится эта штука в 3D
local worldPosition

if promptObject.Parent:IsA("Attachment") then
worldPosition = promptObject.Parent.WorldPosition
elseif promptObject.Parent:IsA("BasePart") or promptObject.Parent:IsA("Model") then
worldPosition = promptObject.Parent:GetPivot().Position
else
-- Если прицепились к чему-то левому, просто прячем фрейм и валим
Prompt_upvr.Visible = false
return
end

-- Теперь превращаем 3D-точку в 2D-точку на экране
-- Заодно получаем флаг onScreen, чтоб знать, видим мы ее или она за спиной
local screenPosition, onScreen = CurrentCamera_upvr:WorldToScreenPoint(worldPosition)

-- Если точка на экране - показываем и двигаем. Если нет - прячем. Логично.
if onScreen then
Prompt_upvr.Visible = true
-- Просто скармливаем X и Y в позицию фрейма
Prompt_upvr.Position = UDim2.fromOffset(screenPosition.X, screenPosition.Y)
else
Prompt_upvr.Visible = false
end
end

-- Цепляемся к событию, когда промпт ПОКАЗАЛСЯ
ProximityPromptService.PromptShown:Connect(function(promptObject)
-- Запускаем нашу функцию на каждый кадр, чтоб фрейм двигался за объектом
RunService_upvr:BindToRenderStep("PromptPos", Enum.RenderPriority.Last.Value + 1, function()
PositionPrompt(promptObject)
end)
end)

-- А это ОБЯЗАТЕЛЬНО. Когда промпт ИСЧЕЗ, надо все остановить.
ProximityPromptService.PromptHidden:Connect(function(promptObject)
-- Убиваем рендер, чтоб не грузить проц зря
RunService_upvr:UnbindFromRenderStep("PromptPos")
-- Ну и прячем сам фрейм
Prompt_upvr.Visible = false
end)