Делаем систему крови или возможность персонажа "красиво" умирать
в прошлом уроке мы сделали ловушки и также улучшили немного нашу систему это последней урок в нашей серии , в следущей серии мы сделаем с вами игру 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 я выдвину пару улучшений который мы сможем добавить
(то куда летит пуля то место и отлетает) тоесть если мы целимя в руку то урон приходится в эту часть тела игрока и эта часть отлетает мы уже сделали с капканом похожее ну а теперь к практике