Зачастую требуется активировать окно GUI (магазин или ещё какая фигня) войдя в определённую зону. Вариантов видел массу, но, зачастую с разными косячками:
- открывается и перс замирает, а мы всего то мимо шли
- открывается, но не закрывается по кнопку на экране не нажмёшь
- дребезг — открывается и тут же закрывается и снова открывается, когда идёшь по границе зоны
А нам надо сделать красиво! ![]()
Итак, варианты подхода различные:
- по расстоянию до игрока
- по касанию парта
- скрипт в игроке
- скрипт в магазине
- один скрипт на всех игроков
Пойдём по другому пути — у нас будет скрипт в зоне и причём локальный. Т.е. он будет обслуживать конкретное место и активироваться на стороне игрока. Т.к. нужна механика именно открытия (вошёл) и закрытия (вышел) GUI, то не будем рассматривать как получить данные с сервера, пусть этим занимается скрипт самого GUI. Наше дело его корректно открыть и закрыть.
Для начала разместим пару вложенных цилиндров — один будет отвечать за открытие, а второй за закрытие. Разница в диаметре должна быть не менее 6 стадов (ширина перса 4 стада) и высотой, над поверхностью не менее высоты прыжка перса для внутреннего цилиндра. Это делается для исключения дребезга — большой будет работать на закрытие GUI, а малый на открытие. Ну и запихнём это в модель.
Далее добавляем в модель Script (не LocalScript) и задаём в нём один параметр:
RunContext = Client
В принципе можем оставить и Legacy или Server и тогда это будет срабатывать на стороне сервера. Допустим, если нам нужна активация какого-нибудь события…
Как видим наш скрипт получил иконку локального скрипта и теперь будет работать только на стороне клиента.
Добавим примитивное GUI, чтобы видеть его активацию:
Теперь, собственно, переходим к скриптам. Что нам нужно?
- Скрыть GUI при загрузке игрока.
- Когда касаемся малого цилиндра — открыть GUI
- Когда перестаём касаться большого — закрыть GUI
--[[ Активация GUI
При загрузке игрока скрываем GUI
При касании Small открываем GUI
При выходе из Big закрываем GUI
]]
local deltaTime = 3 -- время паузы от загрузки игрока для прогрузки GUI
local Players = game:GetService("Players")
local player = Players.LocalPlayer -- только для локального скрипта
local gui = player:WaitForChild("PlayerGui") -- окна конкретного игрока
local me = script.Parent
-- определяем парты через ожидание, т.к. они могут ещё не загрузится
local big = me:WaitForChild("PartBig") -- парт закрытия
local small = me:WaitForChild("PartSmall") -- парт открытия
-- считываем параметры
local myScreen = me.ScreenName.Value -- значение, это с каким Screen мы работаем
local myFrame = me.FrameName.Value -- с каким фреймом в указаном Screen работаем
function OpenGui() -- открываем GUI
local tmp = gui:FindFirstChild(myScreen)
if tmp then
tmp.Enabled = true -- активируем Screen, если он есть
local frame = tmp:FindFirstChild(myFrame)
if frame then
frame.Visible = true -- активируем Frame, если он есть
end
else
warn("OpenGui: Не найден Screen " .. myScreen)
end
end
function CloseGui() -- закрываем GUI
local tmp = gui:FindFirstChild(myScreen)
if tmp then
tmp.Enabled = false -- деактивируем Screen, если он есть
local frame = tmp:FindFirstChild(myFrame)
if frame then
frame.Visible = false -- деактивируем Frame, если он есть
end
else
warn("CloseGui: Не найден Screen " .. myScreen)
end
end
local closeTime = workspace:GetServerTimeNow() + deltaTime
local flag = false
repeat
task.wait() -- чтобы цикл не остановил всю игру
if workspace:GetServerTimeNow() >= closeTime then -- время вышло
flag = true
end
if gui:FindFirstChild(myScreen) then -- Screen подгрузился
flag = true
end
until flag -- будет повторяться пока флаг не станет true
CloseGui() -- при запуске скрипта скрываем GUI
big.TouchEnded:Connect(CloseGui) -- при касании закрываем GUI
small.Touched:Connect(OpenGui) -- при касании открываем GUI
Что нам и нужно было.
Само собой можем добавить на GUI кнопку закрытия окна, а на экран кнопку открытия окна. Работе скрипта это никак не повредит.
А что если надо разные фреймы в одном скрине? Дублируем наше OpenGui и указываем нужные параметры:
И получаем что задумывалось не залезая в скрипт:
Ну и сам плейс:


