https://pastein.ru/t/G7Y
скопируйте уникальную ссылку для отправки
Загрузка данных
-- BossAttacks.lua (внутри модели босса, например, в HumanoidRootPart)
local character = script.Parent.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid")
local animator = humanoid:FindFirstChildOfClass("Animator")
if not animator then
warn("Animator не найден на гуманоиде босса!")
script:Destroy()
end
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BossEvents = ReplicatedStorage:WaitForChild("BossEvents") -- RemoteEvent для синхронизации
-- Анимации атак
local PHASE_1_ATTACK_ANIM_ID = "rbxassetid://+++" -- ID анимации атаки для Фазы 1
local PHASE_2_ATTACK_ANIM_ID = "rbxassetid://+++" -- ID анимации атаки для Фазы 2
-- Анимация покоя босса
local IDLE_ANIMATION_ID = "rbxassetid://+++" -- ID анимации покоя босса (важно для переключения)
-- Урон и параметры атаки
local PHASE_1_ATTACK_DAMAGE = 20
local PHASE_2_ATTACK_DAMAGE = 40 -- Увеличенный урон для Фазы 2
local ATTACK_COOLDOWN = 2 -- Задержка между атаками
local currentBossPhase = 1 -- Отслеживаем текущую фазу босса
local attackDebounce = false
local currentIdleAnimation = nil
-- Защита босса (уменьшение входящего урона)
local BOSS_DAMAGE_REDUCTION_PERCENTAGE = 0.2 -- 20% уменьшение урона (0.2 = 20%)
-- Установка множителя урона для босса
humanoid.HealthChanged:Connect(function(newHealth)
-- Эта логика должна быть в Manager, но здесь для примера, как можно обработать защиту
-- Лучше, чтобы урон обрабатывался сервером, а защита применялась при расчете
-- Например, если игрок наносит 10 урона, босс получает 10 * (1 - 0.2) = 8 урона
end)
-- Функция для проигрывания анимации
local function playAnimation(animationId, loop)
if currentIdleAnimation and currentIdleAnimation.IsPlaying and not loop then
currentIdleAnimation:Stop()
end
local animTrack = animator:LoadAnimation(animationId)
animTrack.Looped = loop or false
animTrack:Play()
return animTrack
end
-- Функция для активации Ragdoll игрока
local function activateRagdoll(playerCharacter, duration)
local playerHumanoid = playerCharacter:FindFirstChildOfClass("Humanoid")
if playerHumanoid then
local parts = {}
for _, part in pairs(playerCharacter:GetChildren()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then
table.insert(parts, part)
end
end
local motors = {}
for _, joint in pairs(playerHumanoid:GetChildren()) do
if joint:IsA("Motor6D") then
table.insert(motors, joint)
joint.Part0 = nil -- Отключаем Motor6D
end
end
for _, part in ipairs(parts) do
part.CanCollide = true
end
playerHumanoid.PlatformStand = true -- Заставляет игрока упасть
playerHumanoid.Sit = true -- Может помочь с ragdoll
task.wait(duration) -- Ждем время ragdoll
-- Восстанавливаем игрока
playerHumanoid.PlatformStand = false
playerHumanoid.Sit = false
for _, motor in ipairs(motors) do
if motor.Part0 == nil then -- Если Motor6D был отключен нами
motor.Part0 = motor.Parent
end
end
for _, part in ipairs(parts) do
-- Опционально: сбросить коллизии, если это необходимо
-- part.CanCollide = false
end
end
end
-- Функция нанесения урона и активации Ragdoll
local function applyDamageAndRagdoll(targetCharacter, damageAmount, ragdollDuration)
local targetHumanoid = targetCharacter:FindFirstChildOfClass("Humanoid")
if targetHumanoid and targetHumanoid.Health > 0 then
targetHumanoid:TakeDamage(damageAmount)
print("Босс нанес " .. damageAmount .. " урона игроку: " .. targetCharacter.Name)
-- Активируем Ragdoll только если игрок еще жив после удара
if targetHumanoid.Health > 0 then
-- Ragdoll должен быть серверной функцией
activateRagdoll(targetCharacter, ragdollDuration)
end
end
end
-- Функция атаки босса
local function bossAttack()
if attackDebounce or humanoid.Health <= 0 then return end
attackDebounce = true
local attackAnimId = (currentBossPhase == 1 and PHASE_1_ATTACK_ANIM_ID) or PHASE_2_ATTACK_ANIM_ID
local currentAttackAnim = playAnimation(attackAnimId, false)
if not currentAttackAnim then
attackDebounce = false
return
end
-- Настраиваем нанесение урона в зависимости от ключевых кадров анимации (если есть)
-- В данном примере, урон будет нанесен через 0.5 секунды после начала анимации.
-- Рекомендуется использовать маркеры (Keyframes) в Animation Editor для точности.
local attackDuration = currentAttackAnim.Length -- Длительность анимации
local hitTime = 0.5 -- Момент удара в анимации (настройте под свою анимацию)
-- Пример использования маркера:
-- currentAttackAnim:GetMarkerReachedSignal("Hit"):Connect(function()
-- -- Логика нанесения урона
-- end)
task.spawn(function()
task.wait(hitTime) -- Ждем момента удара в анимации
if humanoid.Health <= 0 then return end -- Предотвращаем урон, если босс умер во время анимации
local damageToApply = (currentBossPhase == 1 and PHASE_1_ATTACK_DAMAGE) or PHASE_2_ATTACK_DAMAGE
local attackRadius = 8 -- Радиус атаки
for _, player in ipairs(Players:GetPlayers()) do
local playerCharacter = player.Character
if playerCharacter then
local playerHumanoidRootPart = playerCharacter:FindFirstChild("HumanoidRootPart")
if playerHumanoidRootPart then
local distance = (character.HumanoidRootPart.Position - playerHumanoidRootPart.Position).Magnitude
if distance <= attackRadius then
applyDamageAndRagdoll(playerCharacter, damageToApply, 3) -- Нанести урон и Ragdoll на 3 секунды
end
end
end
end
end)
currentAttackAnim.Stopped:Wait() -- Ждем завершения анимации атаки
currentIdleAnimation = playAnimation(IDLE_ANIMATION_ID, true) -- Возвращаемся к анимации покоя
task.wait(ATTACK_COOLDOWN)
attackDebounce = false
end
-- Основной цикл ИИ босса
local function bossAI()
currentIdleAnimation = playAnimation(IDLE_ANIMATION_ID, true) -- Запускаем анимацию покоя сразу
while humanoid.Health > 0 do
-- Пример: Ищем ближайшего игрока
local closestPlayer = nil
local closestDistance = math.huge
for _, player in ipairs(Players:GetPlayers()) do
local playerCharacter = player.Character
if playerCharacter then
local playerHumanoid = playerCharacter:FindFirstChildOfClass("Humanoid")
local playerHumanoidRootPart = playerCharacter:FindFirstChild("HumanoidRootPart")
if playerHumanoid and playerHumanoidRootPart and playerHumanoid.Health > 0 then
local distance = (character.HumanoidRootPart.Position - playerHumanoidRootPart.Position).Magnitude
if distance < closestDistance then
closestDistance = distance
closestPlayer = playerCharacter
end
end
end
end
if closestPlayer and closestDistance <= 15 then -- Если игрок в радиусе 15, атакуем
bossAttack()
else
-- Если игрока нет или он далеко, босс может просто стоять или патрулировать
-- Здесь можно добавить логику движения PathfindingService
task.wait(0.5)
end
task.wait(0.1) -- Небольшая задержка, чтобы не нагружать сервер
end
end
-- Обновление фазы босса
BossEvents.PhaseChanged.OnClientEvent:Connect(function(newPhase)
currentBossPhase = newPhase
print("Босс перешел в фазу: " .. currentBossPhase)
-- Здесь можно добавить эффекты или изменение поведения при смене фазы
end)
-- Запуск ИИ босса после его спавна
BossEvents.BossSpawned.OnClientEvent:Connect(function(bossChar, phase)
if bossChar == character then -- Убедимся, что это наш босс
currentBossPhase = phase
task.spawn(bossAI)
end
end)
-- Если скрипт запускается, а босс уже есть (например, при перезагрузке), запускаем ИИ
if humanoid.Health > 0 then
task.spawn(bossAI)
end