返回博客
Tutorial1 分钟阅读

FiveM 死亡与重生系统:脚本实现真实复活

设计一个精致的 FiveM 死亡与重生系统。流血计时器、EMS 复活、医院流程及适用于 QBCore 和 ESX 的最佳死亡脚本。

Agency Scripts

Agency Scripts 创始人兼首席开发者

检测玩家死亡

死亡与重生系统是任何 FiveM 角色扮演服务器最基本的机制之一,决定玩家生命值归零时发生什么及如何返回游戏。GTA V 默认死亡行为是在简短过场动画后自动在最近医院重生,完全破坏角色扮演沉浸感。要构建合适系统,需在游戏默认处理前拦截死亡状态。每帧监控玩家生命值,使用 GetEntityHealth 并检测其是否降至死亡阈值,ped的阈值为0。检测到死亡时,立即使用 NetworkResurrectLocalPlayer 防止默认死亡画面出现,然后使用 SetPedToRagdoll 模拟失能状态。通过调用禁用默认重生系统 SetPlayerInvincible 在过渡到自定义死亡状态处理器时临时使用。这种方法让您完全控制死亡体验,同时保持视觉真实感。

濒死计时系统

流血倒计时创造了倒地与完全死亡之间的关键窗口,其他玩家可与昏迷者互动。当玩家进入倒地状态时,启动倒计时,表示其缓慢流血。通过NUI覆盖层显著显示剩余时间和相关指令。流血阶段,玩家处于布娃娃或爬行动画,无法使用武器、驾驶车辆或与大多数世界物体互动。允许倒地玩家使用近距离语音聊天,以呼救或角色扮演伤情。计时器时长可配置,通常为5至15分钟,足够EMS现实响应。实现计时器在倒地时受额外伤害加速,施用急救物品如绷带或医疗包时减速或暂停的系统。

-- Client-side death state management
local isDead = false
local bleedoutTime = Config.BleedoutDuration -- seconds
local bleedoutTimer = 0
local lastStandUsed = false

CreateThread(function()
    while true do
        local ped = PlayerPedId()
        local health = GetEntityHealth(ped)

        if health <= 0 and not isDead then
            isDead = true
            bleedoutTimer = bleedoutTime
            lastStandUsed = false

            -- Prevent default death
            NetworkResurrectLocalPlayer(
                GetEntityCoords(ped), GetEntityHeading(ped),
                true, false
            )
            SetEntityHealth(ped, 1)
            SetEntityInvincible(ped, true)
            SetPedToRagdoll(ped, -1, -1, 0, false, false, false)
            ClearPedTasks(ped)

            -- Notify server
            TriggerServerEvent('death:playerDowned', GetEntityCoords(ped))

            -- Show death UI
            SendNUIMessage({ action = 'showDeathScreen', timer = bleedoutTimer })
        end

        if isDead then
            bleedoutTimer = bleedoutTimer - 1
            SendNUIMessage({ action = 'updateTimer', timer = bleedoutTimer })

            -- Disable controls while downed
            DisableControlAction(0, 22, true)  -- jump
            DisableControlAction(0, 24, true)  -- attack
            DisableControlAction(0, 25, true)  -- aim
            DisableControlAction(0, 75, true)  -- exit vehicle

            if bleedoutTimer <= 0 then
                -- Fully dead - offer respawn options
                SendNUIMessage({ action = 'showRespawnOptions' })
            end
        end

        Wait(isDead and 1000 or 500)
    end
end)

最后防线机制

濒死反击机制为倒地玩家提供短暂的反击或爬行逃生机会,为战斗增添战术层面。当玩家首次倒地时,提供一次性激活,使其进入俯卧姿势,在15-30秒内可使用侧臂射击,但准确度和移动速度大幅降低,之后完全倒地。通过将玩家置于爬行动画中实现,使用 TaskPlayAnim 带有基于地面的动画字典,然后暂时重新启用武器使用,但限制仅限手枪。通过摄像机操作施加重武器摇摆效果,模拟重伤时瞄准的困难。最后一战应加速出血计时器的流逝,因为体力消耗加快失血。显示视觉指示,如屏幕去饱和、晕影效果和逐渐减慢的心跳声以营造紧张感。此机制每次死亡周期仅可使用一次以防滥用,且若玩家被爆头击杀则完全禁用,代表瞬间失能的伤口。

EMS互动与复活

EMS复活系统是死亡机制与紧急医疗服务之间创造有意义角色扮演互动的地方。当EMS玩家接近倒地玩家时,应看到一个交互提示,启动治疗序列。治疗过程应持续现实时间,通常为10-20秒,在此期间EMS玩家执行医疗动画,无法移动或防御,制造脆弱性,增加危险区域紧急响应的风险。实现多级治疗:基本稳定,停止流血计时器进展;高级治疗,开始缓慢恢复生命值;完全复活,使玩家恢复站立状态并拥有部分生命值。每个等级都需要EMS玩家库存中的特定医疗物品,如绷带用于稳定,医疗包用于治疗,肾上腺素用于复活。复活后,施加临时Debuff,玩家最大生命值和耐力降低数分钟,代表濒死伤害恢复,防止玩家立即投入战斗。

-- Server-side EMS revival handler
RegisterNetEvent('death:attemptRevive')
AddEventHandler('death:attemptRevive', function(targetId, treatmentType)
    local src = source
    local emsPed = GetPlayerPed(src)
    local targetPed = GetPlayerPed(targetId)

    if not emsPed or not targetPed then return end

    -- Check distance
    local emsCoords = GetEntityCoords(emsPed)
    local targetCoords = GetEntityCoords(targetPed)
    if #(emsCoords - targetCoords) > 3.0 then return end

    -- Check if EMS has required items
    local requiredItems = Config.TreatmentItems[treatmentType]
    for _, item in ipairs(requiredItems) do
        if exports.ox_inventory:Search(src, 'count', item.name) < item.count then
            TriggerClientEvent('ox_lib:notify', src, {
                title = 'Missing supplies',
                description = 'You need: ' .. item.label,
                type = 'error'
            })
            return
        end
    end

    -- Remove items and start treatment
    for _, item in ipairs(requiredItems) do
        exports.ox_inventory:RemoveItem(src, item.name, item.count)
    end

    -- Trigger animations on both players
    TriggerClientEvent('death:startTreatmentAnim', src, targetId)
    TriggerClientEvent('death:receivingTreatment', targetId, src, treatmentType)

    -- After treatment duration, revive
    SetTimeout(Config.TreatmentDurations[treatmentType], function()
        TriggerClientEvent('death:revived', targetId, treatmentType)
        TriggerClientEvent('death:treatmentComplete', src)
    end)
end)

医院重生系统

当出血计时器到期且无 EMS 干预或玩家选择放弃时,医院复活系统负责将其带回游戏。向玩家展示死亡界面 NUI,显示两个选项:等待 EMS(带有附近值班医护的视觉指示)或支付费用在最近医院复活。医院复活非即时,应用加载动画或黑屏渐变过渡,然后传送玩家至医院内部,播放醒来动画,使用合适的医院房间内饰和床道具。收取根据玩家当前财务状况比例计算的医疗费,避免对富玩家费用过低或对新手过重。复活后施加受伤冷却期,玩家属性降低且穿着医院病号服,期间不可换装。追踪死亡频率,实施软惩罚:短时间内频繁死亡的玩家将面临更高复活费用和更长恢复期,劝阻鲁莽行为,同时不使偶发死亡过于惩罚。

死亡屏幕 UI 设计

死亡屏幕是玩家处于最脆弱游戏时刻看到的主要界面,因此需简洁、信息丰富且富有氛围。构建为 NUI 覆盖层,玩家进入倒地状态时控制屏幕。应用渐进去饱和滤镜,去除游戏世界色彩,屏幕边缘有随心跳节奏脉动的微红晕,随着流血倒计时减少,轻微模糊效果增强。屏幕中央或顶部显著显示剩余流血时间倒计时及操作提示:按 E 通过游戏内电话呼救,长按 G 激活最后抵抗(若可用),长按 X 放弃并在医院重生。EMS 抵达时显示通知及预计时间,显示附近可能帮助玩家的名字和距离。保持 UI 简洁,避免在紧张沉浸时刻屏幕杂乱。使用细腻的 GSAP 动画实现 UI 元素淡入和计时器倒计时,保持视觉精致。

伤害与恢复系统

扩展死亡系统,增加复活后持续的伤害层,增强深度与后果。当玩家被 EMS 复活或在医院重生时,根据死亡原因分配伤害效果。枪伤导致跛行动画,移动速度降低20%,持续15分钟。车祸造成眩晕效果,伴随周期性屏幕震动,持续10分钟。高处坠落导致腿部受伤,无法冲刺。溺水引发咳嗽动画和耐力降低。将活跃伤害存储在玩家状态包中,确保跨脚本重启持续存在,并对其他玩家可见。创建伤害治疗路径,玩家可访问医生 NPC 或玩家药剂师,接受药物减少伤害持续时间。实现疼痛系统,严重伤害时偶尔屏幕闪烁并伴有压抑呻吟声,附近玩家可听见,创造关心市民或掠夺性罪犯识别并与受伤玩家互动的机会。伤害系统弥合死亡与完全恢复之间的差距,使每次死亡成为多阶段体验,延长角色扮演而非瞬时不便。

配置和管理员控制

一个灵活的死亡系统需要全面的配置选项和管理工具。为服务器拥有者提供一个配置文件,控制所有时间相关参数:流血持续时间、最后抵抗持续时间及可用性、医院重生费用公式、EMS各等级治疗时间、不同伤害效果持续时间,以及死亡间隔冷却时间以触发升级惩罚。添加管理员命令,允许工作人员即时复活玩家、为管理目的击杀玩家、调整特定玩家的流血计时器、清除所有活跃伤害,以及为事件或管理情况切换无敌模式。构建死亡日志,记录每次玩家死亡的时间戳、位置坐标、死亡原因、杀手标识(如适用)、EMS响应时间,以及玩家是否被复活或重生。通过管理面板公开此日志,方便工作人员调查可疑模式,如同一地点反复死亡表明刷点,或异常快速复活暗示EMS滥用。死亡系统应发出事件供其他脚本挂钩,使你的职业系统能通知值班EMS附近倒地玩家,警察系统能标记频繁暴力死亡地点。

准备好开始了吗?

在我们的商店获取脚本,或加入 Discord 获取支持、更新以及新功能预告。