Делаем систему крови или возможность персонажа "красиво" умирать
в прошлом уроке мы сделали ловушки и также улучшили немного нашу систему это последней урок в нашей серии , в следущей серии мы сделаем с вами игру Doors
теперь перейдем к главному как сделать чтобы при стрельбе в игрока из оружия у него появлялась кровь?
на этот раз я тоже буду использовать модельку из тулбокса про создание моделей и билдинг я сделаю отдельный урок вы если хотите может использовать свой автомат
но сначала мы с вами сделаем кнопку + меню выбора оружия
в папке StarterGui мы добавляем screengui
В Roblox Studio ScreenGui
(сокращение от "Screen Graphical User Interface") — это элемент интерфейса, который отображает графические элементы на экране игрока. ScreenGui
используется для создания различных интерфейсов, таких как кнопки, текстовые поля, шкалы здоровья, карты и другие визуальные элементы, которые игроки видят во время игры.
Основные характеристики ScreenGui
- Расположение на экране:
ScreenGui
всегда отображается поверх игры и фиксируется к экрану игрока. Это означает, что элементы внутриScreenGui
не будут изменять своё положение относительно экрана, даже если камера или игрок будут двигаться. - Родительский объект для GUI-элементов: Внутри
ScreenGui
можно добавлять различные элементы интерфейса, такие как:Все эти элементы должны быть вложены вScreenGui
для того, чтобы быть видимыми на экране. TextLabel
: Текстовые метки.TextButton
: Кнопки с текстом.ImageLabel
: Изображения.Frame
: Прямоугольные области, используемые для группировки других элементов.- И другие GUI-объекты.
- Область отображения:
ScreenGui
всегда отображается в пределах области экрана игрока. Это означает, что он "привязан" к экрану и не будет изменяться в зависимости от игрового мира. Например, элементы интерфейса, такие как панели управления, инвентари, карты и другие элементы HUD (Head-Up Display), всегда остаются на экране, независимо от позиции игрока в игровом мире.
Дизайн кнопки вы можете выбрать сами в Properties для тех кто не знает как я покажу как сделать такую же кнопку или как настроить ее внешний вид
для тех у кого также как у меня нету Properties
Мы заходим во View и выбираем properties
делаю черный цвет нашего бэкграунда
и увеличиваем размер текста в пункте TextScale
Также еще в нашу папку Screengui добавляем обьект с именем Frame
(я также если что поменял имя нашего Textbutton на MenuButton для удобства)
Также добавляем внутрь нашего ScreenGui cкрипт
Только поправку не Script а Localscript щас обьясню почему
В Roblox Studio существуют два основных типа скриптов для работы с Lua-кодом: Script и LocalScript. Они отличаются главным образом тем, где и как они выполняются, а также какие функции и данные им доступны. Вот основные различия:
1. Script (Скрипт)
- Место выполнения: Скрипты выполняются на стороне сервера. Это означает, что код внутри Script запускается и работает на сервере Roblox.
- Область видимости: Скрипты имеют доступ к серверным функциям и объектам. Они могут изменять состояние игры, доступное для всех игроков.
- Примеры использования:
2. LocalScript (Локальный скрипт)
- Место выполнения: Локальные скрипты выполняются на стороне клиента, то есть непосредственно на устройстве игрока.
- Область видимости: Локальные скрипты имеют доступ к объектам и функциям, которые доступны только клиенту, например, графический интерфейс пользователя (GUI) или управление камерой.
- Примеры использования:
3. Особенности взаимодействия
- LocalScript не может напрямую изменять объекты на сервере, для этого ему нужно использовать RemoteEvent или RemoteFunction для отправки запроса на сервер, чтобы серверный Script мог выполнить необходимую работу.
- Script не может напрямую взаимодействовать с клиентскими объектами, такими как интерфейс пользователя, и тоже должен использовать удаленные вызовы для взаимодействия с клиентом.
4. Где они могут быть размещены:
- Script можно размещать в ServerScriptService, Workspace и других местах, которые доступны серверу.
- LocalScript должен быть размещен в объектах, которые доступны клиенту, таких как StarterPlayerScripts, StarterCharacterScripts, StarterGui и некоторых других.
Таким образом, основное различие между Script и LocalScript в Roblox Studio заключается в том, где они выполняются (на сервере или на клиенте) и какие функции они могут использовать.
также LocalScript гораздо легче взломать поэтому все важные манипуляции и данные размещяем в script чтобы читеры не могли получить существенное превосходство
в нашей переменной мы обращаемся к родителю нашего скрипта (родитель это папка а ребенок материал который расположен в папке в нашем же случае Frame является ребенком StarterGui
- Это переменная, которая ссылается на объект типа
TextButton
(кнопку), которую мы создали вScreenGui
. Эта кнопка отображается на экране игрока и может быть нажата игроком. - у нас есть кнопка с именем
MenuButton
, переменнаяmenuButton
содержит ссылку на этот объект.
- Это событие, которое срабатывает, когда пользователь нажимает на кнопку с левой кнопкой мыши.
- В Roblox все GUI-элементы могут иметь события, которые запускаются при определённых действиях, таких как нажатие кнопки или перемещение мыши. В данном случае событие
MouseButton1Click
связано с левым щелчком мыши по кнопке.
- Метод
Connect
используется для подключения функции к событию. Когда событие происходит (в данном случае, когда пользователь нажимает на кнопку), вызывается подключенная функция. OnOff
— это имя нашей функции, котораячс будет выполнена, когда событиеMouseButton1Click
сработает. Например, функцияOnOff
может управлять видимостью меню, показывая или скрывая его.
теперь я добавил 3 ImageButton это кнопка с картинкой я на каждой кнопке размещу картинку оружия которую получит персонаж при нажатии а также переименую каждую кнопку в названия оружия
Теперь после того как я пронумеровал их, мы в Properties поставим саму картинку
теперья на скорую руку подробал изображения вы можете поставить свои так как эти далеко не самые лучшие
про дизайн gui будет отдельная статья + в конце статьи будет ссылка на полезный плагин
теперь нужно найти модельки наших оружий причем которые работают и могут стрелять
после того как нашли наши модельки переносим их в ServerStorage (это наше хранилище где можно хранить предметы карты и прочее)
и теперь добавляем в ReplicatedStorage Remove event
Remote Event в Roblox Studio — это один из ключевых механизмов, позволяющих взаимодействовать между клиентом и сервером в игре. Давайте разберёмся, что это такое, зачем он нужен и как его использовать.
Что такое Remote Event?
Remote Event — это объект, который используется для передачи сообщений между клиентом (игроком) и сервером (серверной частью игры). В Roblox, игры работают по принципу клиент-серверной архитектуры, где клиент и сервер — это два разных "мира":
- Клиент — это устройство игрока (например, его компьютер или телефон), которое отображает игру, позволяет управлять персонажем и так далее.
- Сервер — это основная часть игры, которая управляет всей логикой, например, где находятся объекты, как они взаимодействуют, и так далее.
Из-за этой разделённости клиент и сервер не могут напрямую "видеть" или управлять друг другом, поэтому нужен способ передавать данные между ними. И вот тут на сцену выходит Remote Event.
Зачем нужен Remote Event?
- Безопасность: Сервер управляет важной логикой игры, такой как проверка правил, обработка игровых данных, и так далее. Если бы клиент мог сам всё это контролировать, то игроки могли бы читерить, меняя данные у себя на устройстве. Поэтому клиент не может напрямую изменять важные данные на сервере — ему нужно отправлять запросы с помощью Remote Event, а сервер уже решает, что с этими данными делать.
- Синхронизация: В игре могут быть действия, которые нужно синхронизировать между разными игроками. Например, если один игрок нажал кнопку, то у всех остальных игроков должно что-то произойти. Для этого клиент отправляет событие на сервер, а сервер уже рассылает это событие всем клиентам.
Как работает Remote Event?
Работа с Remote Event основана на двух основных методах:
- FireServer — используется клиентом для отправки сообщения на сервер.
- FireClient — используется сервером для отправки сообщения на конкретный клиент.
- FireAllClients — используется сервером для отправки сообщения всем клиентам.
Пример использования Remote Event
Представим, что у вас в игре есть кнопка, которую игрок нажимает, и это должно привести к каким-то изменениям на сервере, например, выдаче очков.
- На стороне клиента:
- Игрок нажимает кнопку.
- Скрипт на клиенте (местный скрипт) вызывает
RemoteEvent:FireServer()
, передавая какие-то данные на сервер, например, количество очков. - На стороне сервера:
и сегодня мы как раз таки будем выдывать предмет нашему игру с помощью данной конструкции
так а теперь переходим к скрипту
напомню что надо localsript так как мы будем использовать клиент → серверную архитектуру мы будем обращаться из клиента (компьютера игрока) на серверную функцию мы с вами уже делали такой трюк в этой статье
https://teletype.in/@antichrist_squid/x4AvHZLlEeQ
Переменные
luaCopy codelocal ak47 = script.Parent:WaitForChild("AK-47 BUTTON") local m12button = script.Parent:WaitForChild("m12 button") local awpbutton = script.Parent:WaitForChild("AWP Button")
ak47
,m12button
,awpbutton
: Здесь создаются три переменные, которые будут ссылаться на кнопки которые мы с вами создали. Они используются для того, чтобы привязать к ним функционал. Каждая переменная ссылается на кнопку с соответствующим названием ("AK-47 BUTTON", "m12 button", "AWP Button"). Эти кнопки находятся в родительском объектеscript.Parent
, который указывает на родительский элемент скрипта (обычно это GUI объект).
Функция для выдачи оружия
luaCopy codelocal givingweapon = game.ReplicatedStorage.RemoteEvent
givingweapon
: Создаётся переменнаяgivingweapon
, которая ссылается на событие типаRemoteEvent
, находящееся вReplicatedStorage
. Это событие будет использовано для отправки сигнала с клиента на сервер (что-то вроде межсессионного сообщения между клиентом и сервером).
Подключение кнопки к функции
luaCopy codeak47.MouseButton1Click:Connect(function(plr) givingweapon:FireServer(plr) end)
ak47.MouseButton1Click:Connect(function(plr) ... end)
: Эта строка кода говорит, что когда игрок нажимает на кнопкуak47
, выполняется функция, переданная вConnect
.givingweapon:FireServer(plr)
: Внутри функции вызывается методFireServer
, который отправляет сигнал на сервер с параметромplr
(в данном случае, это, вероятно, ссылка на объект игрока).
Что это всё значит?
- Переменные
ak47
,m12button
, иawpbutton
: Эти переменные позволяют вам работать с конкретными кнопками на пользовательском интерфейсе (UI). - Событие
RemoteEvent
(givingweapon
): Оно используется для того, чтобы сигнализировать серверу о необходимости выдать игроку оружие. Это нужно, поскольку в Roblox действия, связанные с изменением данных игры, часто должны быть выполнены на сервере. - Обработка нажатия кнопки: Когда игрок кликает по кнопке
ak47
, клиент отправляет запрос на сервер черезgivingweapon:FireServer(plr)
. Сервер, получив этот сигнал, может выполнить выдачу оружия.
грубо говоря при нажатии наш скрипт говорит серверу "Эй, босс, этому игроку нужен АК-47!" И сервер мгновенно достаёт оружие и вручает его
хорошо а теперь пришло время к реализации серверного скрипта
Что такое ServerScriptService?
Когда вы создаёте игру в Roblox, существует два основных типа скриптов: серверные и клиентские. Серверные скрипты работают на сервере и обычно используются для выполнения задач, которые должны быть одинаковыми для всех игроков в игре, например:
- Управление игровыми объектами и их состояниями (например, позиция или видимость объектов).
- Обработка действий, связанных с несколькими игроками (например, синхронизация состояния игры).
- Управление экономикой игры (например, выдача внутриигровой валюты или предметов).
Почему важно использовать ServerScriptService?
- Безопасность: Скрипты, размещенные в ServerScriptService, не видны и недоступны для игроков. Это важно, потому что игроки не могут их изменить или взломать. Например, если вы хотите сохранить логику выдачи наград или обработку покупок, лучше разместить этот код в ServerScriptService.
- Организация: ServerScriptService помогает структурировать ваш проект. Вы можете хранить все серверные скрипты в одном месте, что упрощает их управление и редактирование.
- Серверная логика: В ServerScriptService можно размещать скрипты, которые управляют тем, что происходит на сервере. Например, когда игрок собирает предмет, серверный скрипт может обрабатывать этот процесс, обеспечивая правильное взаимодействие между всеми игроками.
1. Подключение к удалённому событию (RemoteEvent)
local givingweapon = game.ReplicatedStorage.RemoteEvent
- Эта строка находит и сохраняет ссылку на объект
RemoteEvent
, который находится вReplicatedStorage
. RemoteEvent
— это специальный объект в Roblox, который позволяет клиенту (игроку) и серверу обмениваться сообщениями. В данном случае, это объект, который сервер будет слушать, чтобы понять, когда игрок запросил оружие.
2. Обработка события на сервере
degivingweapon.OnServeшщEvent:Connect(function(plr)
- Этот код прослушивает событие
OnServerEvent
, которое срабатывает, когда клиент отправляет сигнал на сервер, используяRemoteEvent
. - Когда происходит это событие, вызывается функция, которая получает параметр
plr
(это игрок, который отправил запрос).
3. Клонирование и выдача оружия
game.ServerStorage["ak47"]:Clone().Parent = plr:WaitForChild("Backpack") game.ServerStorage["ak47"]:Clone().Parent = plr:WaitForChild("StarterGear")
game.ServerStorage["ak47"]
— этот код обращается к объектуak47
, который хранится вServerStorage
.ServerStorage
— это хранилище, в котором хранятся объекты, доступные только серверу. Игроки не могут получить к ним доступ напрямую.Clone()
— эта команда создаёт копию объектаak47
.Parent = plr:WaitForChild("Backpack")
— эта часть кода перемещает клонированный объект в рюкзак игрока (Backpack
). Таким образом, оружие появляется у игрока и он может его использовать.Parent = plr:WaitForChild("StarterGear")
— эта строка по вашему желанию она отвечает за то что даже после смерти нашего персонажа во время респпуана у него всероно останется
также в качестве практики реализуете красную кнопку при нажатии на которую у нас пропадает наша меню
добавляете в это место скрипт и копируете туда наш код от капкана
теперь добавим несколько изменений
нашу основую функцию не меняем единственное что мы поменяем это условие ее вызова
для начала в функции stopBleeding убираем редактирование кирпича
теперь просто удаляем функцию onTouch она нам не нужна:
теперь пишем новую функцию onHealthChanged
также для вашего удобства я специально расставил коментарии чтобы было визуально удобно смотреть чтобы даже только смотря картинки было все понятно и ясно.
local function onHealthChanged(health) -- Если здоровье уменьшилось и персонаж не кровоточит, запускаем кровотечение if health < humanoid.MaxHealth and not isBleeding then startBleeding(humanoid.Parent) end end
- Определение функции:
local function onHealthChanged(health)
— Эта строка объявляет локальную функцию с именемonHealthChanged
. Функция принимает один параметр —health
, который представляет текущее значение здоровья персонажа.- Проверка состояния:
if health < humanoid.MaxHealth and not isBleeding then
— Эта строка проверяет два условия:health < humanoid.MaxHealth
— Проверяет, уменьшилось ли текущее здоровье (health
) по сравнению с максимальным здоровьем (humanoid.MaxHealth
). Это значит, что персонаж получил урон.not isBleeding
— Проверяет, не кровоточит ли уже персонаж (isBleeding
должно быть переменной, которая указывает, кровоточит ли персонаж в данный момент).- Запуск эффекта кровотечения:
Что делает этот код: Этот код следит за изменением здоровья персонажа. Когда здоровье персонажа уменьшается (то есть, когда он получает урон) и при этом он не кровоточит, код запускает функцию, которая инициирует эффект кровотечения.
теперь пишем следующую функцию которая будет отслеживать нашего игрока
- Функция
onCharacterAdded
: - Эта функция вызывается каждый раз, когда к игроку добавляется новый персонаж в игру (например, когда игрок респавнится).
- Функция получает параметр
character
, который представляет собой объект персонажа игрока. - Внутри функции она пытается найти объект
Humanoid
в персонаже.Humanoid
— это компонент, который управляет здоровьем, анимациями и другими аспектами персонажа. - Если
Humanoid
найден (то есть, если он существует), функция подключает две обработки событий: HealthChanged
: Событие, которое срабатывает каждый раз, когда изменяется здоровье персонажа. Для этого события подключается функцияonHealthChanged
, которая будет вызвана при изменении здоровья.Died
: Событие, которое срабатывает, когда персонаж умирает. Для этого события подключается функцияstopBleeding
, которая остановит кровотечение (или выполнит другую соответствующую логику).- Подключение к событию
CharacterAdded
: player.CharacterAdded:Connect(onCharacterAdded)
— эта строка подключает функциюonCharacterAdded
к событию, которое срабатывает каждый раз, когда у игрока добавляется новый персонаж.- Это означает, что каждый раз, когда персонаж игрока появляется или респавнится, функция
onCharacterAdded
будет вызвана, чтобы установить необходимые обработчики событий. - Проверка существующего персонажа:
Общий смысл: Этот код обеспечивает автоматическое подключение функций для обработки изменений здоровья и смерти персонажа игрока. Он делает это как при создании нового персонажа, так и при наличии персонажа в момент выполнения скрипта.
теперь можете тестировать все должно работать
я думаю уже после серии про Doors я выдвину пару улучшений который мы сможем добавить
(то куда летит пуля то место и отлетает) тоесть если мы целимя в руку то урон приходится в эту часть тела игрока и эта часть отлетает мы уже сделали с капканом похожее ну а теперь к практике