Roblox · Песочница · урок 7
Сытость падает со временем — на нуле уходит здоровье. Яблоки растут на яблоне. Бег тратит выносливость.
Синим — что добавляем на этом уроке.
ServerStorage └─ Food (Folder) └─ Apple (Tool) — Handle → Eat (Sound); FoodValue (IntValue 25); FoodScript (Animation) Workspace └─ AppleTree (Model) — Trunk, Leaves, Apples (Model) └─ PromptPart (Part) — ProximityPrompt → TakingFood ServerScriptService └─ HungerServer (Script) StarterPlayer → StarterCharacterScripts └─ Run (LocalScript) — заменён: бег + выносливость StarterGui ├─ HungerGui (ScreenGui) — Background → Bar; HungerLocal └─ StaminaGui (ScreenGui) — Background → Bar; Enabled выкл.
Где: ServerScriptService · Script
Зачем: Сытость.
-- игроки
local Players = game:GetService("Players")
-- раз в сколько секунд голод растёт
local FREQUENCY = 4
-- на сколько падает сытость
local DECREASE = 2
-- урон от голода, когда сытость 0
local STARVE_DAMAGE = 5
-- игрок зашёл
local function Setup(player)
-- сытость
local hunger = Instance.new("IntValue")
-- имя — его читают интерфейс и еда
hunger.Name = "Hunger"
-- сыт
hunger.Value = 100
-- в игрока
hunger.Parent = player
-- после возрождения — снова сыт
player.CharacterAdded:Connect(function() hunger.Value = 100 end)
-- пока игрок в игре
while player.Parent do
-- ждём
task.wait(FREQUENCY)
-- его Humanoid
local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
-- жив
if humanoid and humanoid.Health > 0 then
-- ещё не голоден
if hunger.Value > 0 then
-- сытость падает
hunger.Value = math.max(hunger.Value - DECREASE, 0)
-- голоден
else
-- здоровье понемногу уходит
humanoid:TakeDamage(STARVE_DAMAGE)
-- конец проверки
end
-- конец проверки
end
-- конец цикла
end
-- конец функции
end
-- новые игроки
Players.PlayerAdded:Connect(Setup)
-- кто зашёл раньше скрипта
for _, player in ipairs(Players:GetPlayers()) do task.spawn(Setup, player) endГде: StarterGui → HungerGui · LocalScript
Зачем: Полоса сытости.
-- игроки
local Players = game:GetService("Players")
-- сытость
local hunger = Players.LocalPlayer:WaitForChild("Hunger")
-- полоса (растёт снизу вверх)
local bar = script.Parent:WaitForChild("Background"):WaitForChild("Bar")
-- обновить полосу
local function Update()
-- высота = сытость
bar.Size = UDim2.fromScale(1, math.clamp(hunger.Value / 100, 0, 1))
-- конец функции
end
-- изменилась
hunger.Changed:Connect(Update)
-- сразу
Update()Где: ServerStorage → Food → Apple · Script
Зачем: Съесть яблоко.
-- яблоко
local tool = script.Parent
-- сколько сытости даёт
local foodValue = tool:WaitForChild("FoodValue")
-- хруст
local eatSound = tool:WaitForChild("Handle"):WaitForChild("Eat")
-- анимация еды
local anim = script:WaitForChild("Animation")
-- уже съедено
local eaten = false
-- клик — съесть
tool.Activated:Connect(function()
-- кто ест
local character = tool.Parent
-- игрок
local player = game.Players:GetPlayerFromCharacter(character)
-- Humanoid
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- уже, не игрок или погиб
if eaten or not player or not humanoid or humanoid.Health <= 0 then return end
-- съедено
eaten = true
-- анимация
if anim.AnimationId ~= "" then humanoid:FindFirstChildOfClass("Animator"):LoadAnimation(anim):Play() end
-- хруст
eatSound:Play()
-- жуём
task.wait(1)
-- сытость
local hunger = player:FindFirstChild("Hunger")
-- сытость сервер считает сам, не выше 100
if hunger then hunger.Value = math.min(hunger.Value + foodValue.Value, 100) end
-- яблока больше нет
tool:Destroy()
-- конец функции
end)Где: Workspace → AppleTree → PromptPart → ProximityPrompt · Script
Зачем: Сорвать яблоко.
-- образец яблока
local SS = game:GetService("ServerStorage")
-- ProximityPrompt «Сорвать»
local prompt = script.Parent
-- яблоня: Prompt → PromptPart → AppleTree
local tree = prompt.Parent.Parent
-- яблоко-инструмент
local apple = SS:WaitForChild("Food"):WaitForChild("Apple")
-- через сколько секунд вырастут снова
local REGROW = 10
-- сорвали
prompt.Triggered:Connect(function(player)
-- яблоки на дереве (декор)
local apples = tree:FindFirstChild("Apples")
-- уже сорваны
if not apples then return end
-- яблоко в рюкзак
apple:Clone().Parent = player.Backpack
-- яблоки пропали с дерева
apples.Parent = nil
-- сорвать нечего
prompt.Enabled = false
-- растут
task.wait(REGROW)
-- снова на дереве
apples.Parent = tree
-- можно рвать
prompt.Enabled = true
-- конец функции
end)Где: StarterPlayer → StarterCharacterScripts · LocalScript
Зачем: Бег с выносливостью.
-- клавиатура
local UIS = game:GetService("UserInputService")
-- каждый кадр
local RunService = game:GetService("RunService")
-- игроки
local Players = game:GetService("Players")
-- персонаж
local character = script.Parent
-- Humanoid
local humanoid = character:WaitForChild("Humanoid")
-- полоса выносливости
local gui = Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("StaminaGui")
-- полоса
local bar = gui:WaitForChild("Background"):WaitForChild("Bar")
-- запас
local MAX = 150
-- тратится в секунду
local DRAIN = 30
-- восстанавливается в секунду
local REGEN = 20
-- бег
local RUN_SPEED = 25
-- шаг
local WALK_SPEED = 16
-- сейчас
local stamina = MAX
-- Shift зажат
local shift = false
-- бежим
local running = false
-- нажали
UIS.InputBegan:Connect(function(input, processed)
-- Shift
if not processed and input.KeyCode == Enum.KeyCode.LeftShift then shift = true end
-- конец функции
end)
-- отпустили
UIS.InputEnded:Connect(function(input)
-- Shift
if input.KeyCode == Enum.KeyCode.LeftShift then shift = false end
-- конец функции
end)
-- каждый кадр
RunService.Heartbeat:Connect(function(dt)
-- погиб или сидит — не бежим
if humanoid.Health <= 0 or character:GetAttribute("Crouching") then running = false return end
-- можно бежать
local want = shift and humanoid.MoveDirection.Magnitude > 0 and stamina > 0
-- бежим
if want then
-- тратим
stamina = math.max(stamina - DRAIN * dt, 0)
-- Shift отпущен
elseif not shift then
-- отдыхаем
stamina = math.min(stamina + REGEN * dt, MAX)
-- конец проверки
end
-- состояние сменилось
if want ~= running then
-- запоминаем
running = want
-- скорость меняем только в этот момент
humanoid.WalkSpeed = want and RUN_SPEED or WALK_SPEED
-- конец проверки
end
-- полная — полоску прячем
gui.Enabled = stamina < MAX
-- длина полосы
bar.Size = UDim2.fromScale(stamina / MAX, 1)
-- конец функции
end)Запусти Play (или Run) и убедись: