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