CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

不屈志:致命一刀剩一口,三秒金身讨回来

2026-10-01 04:37 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【游戏功能】

不屈志的全机制就一句:被打到该死的那个瞬间,志气发作——血剩一口、三秒免伤、刀速翻倍,一场仗只发作一次——这是玩家和死亡之间签的第一份合同。它是玩家和死亡之间的一纸合同:死亡可以来,但第一次得空手而归。这篇的核心代码照引擎技能脚本的全规格写:配置表、金环构件、触发钩子、定时器、调试按钮,一根骨头不少,从头到尾一个模块讲透。

一、效果演示:一口血,三口气

演示场里玩家血条旁挂着一颗金色的"志气未发"小条。大怪的刀一刀二十六、每六秒一记五十的大抡——血线一路往下走,跌到该死的那个瞬间,金环当场炸开:血钉在一、头顶蹦出十七号大字的"不屈!"、周身金色光环转起来;三秒里所有落刀只蹦"免疫",你的普攻从一秒一口提速到一口十五,把刚才挨的刀一口口讨回去。三秒一过金光散掉,"志气已尽"四个灰字挂上——这一场,命只有一条底牌。演示里故意让大怪的第二记五十落地在志气已尽之后,同样的刀,这次是真的疼。

demo
 fx-undying

二、底层原理:一个死亡拦截钩子加一份一次性旗标

模块的全部机关是一对搭档。触发钩子挂在玩家的扣血入口上:每一次伤害先做死亡预演——血量减去这一刀会不会归零——会,且志气旗标还立着,就把这一刀改判成"剩一口",旗标倒下、三秒免伤层和攻速层同时挂上。旗标是一次性的:发作过就永远立不起来,这一场仗的合同已经兑现。免伤层写在扣血入口的判链最前端,志气期的每一刀在预演之前就被拦下蹦"免疫"——拦截、改判、免伤三层逻辑共用一个入口,是这套机制账目永远平的原因。

三、核心代码:完整模块(上·骨架)

lua
--------------------------------------------------------------------------------
-- @file        Undying.lua
-- @brief       不屈志 —— 致命一刀剩一口,三秒金身讨回来
--              客户端表现模块:配置表 / 金环构件 / 死亡拦截 / 定时器
--------------------------------------------------------------------------------

local Undying = {}

--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
    GLOW_LIFE     = 3.0,        -- 志气三秒
    GLOW_AMP      = 2.0,        -- 志气期刀速乘二
    IMMUNE_TEXT   = "免疫",
    LEFT_HP       = 1,          -- 剩一口血

    -- 颜色
    COLOR_WILL    = "#ffd866",  -- 意志金
    COLOR_DEEP    = "#7a5a12",  -- 深金
    COLOR_GHOST   = "#fff3c4",  -- 残光

    ZORDER_GROUND = 118,
    ZORDER_RING   = 134,
    ZORDER_EFFECT = 135,

    AUTOINC_BASE  = 926000,
}

--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _will      = true           -- 志气旗标:一场仗只发作一次
local _glowT     = 0              -- 发作余时
local _scheduler = nil
local _autoInc   = 0

local m_cos = math.cos
local m_sin = math.sin

--------------------------------------------------------------------------------
-- 辅助函数
--------------------------------------------------------------------------------
local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "UDY", CONST.AUTOINC_BASE + _autoInc)
end

local function GetMyPos()
    local x = SL:GetValue("ACTOR_POSITION_X", SL:GetValue("USER_ID"))
    local y = SL:GetValue("ACTOR_POSITION_Y", SL:GetValue("USER_ID"))
    if not x or not y then return nil end
    return { x = x, y = y }
end

local function SafeRemove(node)
    if node and not GUI:Widget_IsNull(node) then
        GUI:removeFromParent(node)
    end
end

local function ShowTip(msg)
    if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end

---金环构件:志气发作与免伤期的周身光环
local function CreateWillRing()
    local mp = GetMyPos()
    if not mp then return end
    local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID("Ring"),
        mp.x, mp.y - 46, 0, 0, false)
    GUI:setLocalZOrder(node, CONST.ZORDER_RING)
    for i = 1, 28 do
        local a1 = (i - 1) / 28 * 6.28
        local a2 = i / 28 * 6.28
        GUI:DrawLine_Create(node, string.format("g_%d", i), 0, 0, 3,
            m_cos(a1) * 30, m_sin(a1) * 56, m_cos(a2) * 30, m_sin(a2) * 56,
            CONST.COLOR_WILL, 210)
    end
    GUI:runAction(node, GUI:ActionSequence(
        GUI:ActionFadeIn(0.10),
        GUI:DelayTime(2.4),
        GUI:ActionFadeOut(0.5),
        GUI:CallFunc(function() SafeRemove(node) end)
    ))
    return node
end

骨架先立两块基石。_will 是布尔旗标不是计数器——一场一次的机制用计数器写,迟早有人把它改成"两次",机制的尊严就在"只此一次"。金环构件的椭圆用纵轴五十六横轴三十的比例画——贴着人形的高宽比画环,环才是长在人身上的,正圆的环是结界不是志气。

四、核心代码:完整模块(下·定时器与死亡拦截)

lua
--------------------------------------------------------------------------------
-- 死亡拦截:扣血入口的第一道关
--------------------------------------------------------------------------------
local function OnPlayerHurt(raw)
    if _glowT > 0 then
        SL:TipAboveMe(CONST.IMMUNE_TEXT)
        return
    end
    local hp = SL:GetValue("ACTOR_HP", SL:GetValue("USER_ID"))
    if _will and hp and hp - raw <= 0 then
        _will = false
        _glowT = CONST.GLOW_LIFE
        SL:SetHp(SL:GetValue("USER_ID"), CONST.LEFT_HP)
        SL:SetAttackSpeedAmp(CONST.GLOW_AMP)
        CreateWillRing()
        SL:TipAboveMe("不屈!")
        SL:ScreenShake(5, 0.30)
        return
    end
    SL:PlayerHurt(raw)
end

--------------------------------------------------------------------------------
-- 攻速层的挂载与卸载
--------------------------------------------------------------------------------
local function Glow_Update(dt)
    if _glowT <= 0 then return end
    _glowT = _glowT - dt
    if _glowT <= 0 then
        SL:SetAttackSpeedAmp(1.0)
        ShowTip("志气散了——接下来的刀要自己挡")
    end
end

--------------------------------------------------------------------------------
-- 定时器与调试
--------------------------------------------------------------------------------
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        Glow_Update(dt)
    end, 0.02)
end

SL:RegisterLUAEvent(LUA_EVENT_LOCAL_HURT, "UDY_Hurt", function(data)
    if data and data.raw then
        OnPlayerHurt(data.raw)
    end
end)

SL:RegisterLUAEvent(LUA_EVENT_SCENE_CLEAR, "UDY_Clear", function()
    _will = true
    _glowT = 0
    SL:SetAttackSpeedAmp(1.0)
end)

SL:ScheduleOnce(function()
    ShowTip("技能已加载: 不屈志 (调试按钮触发)")
end, 1.0)

return Undying

下半场的题眼是 OnPlayerHurt 这道三段闸门:免伤判志气期、改判看旗标、落账走原路——三段的顺序不能动,免伤写在最前,志气期的刀永远进不了死亡预演。改判分支里 SetHp 和攻速层同帧挂上,发作的每一件事都在同一帧完成——分帧的版本会出现"剩了一口血但刀还是慢的"半残状态。金环构件挂的是动作序列的自毁——构件自己管自己的寿命,志气散了环自然淡出,清零逻辑不用追着视觉跑。场景清空钩子把旗标复原成真:新的一场仗,合同重新签,这是"一场一次"能被玩家信任的前提。免伤小字的弹出频率也要管——志气期的连续快刀会连珠炮似的刷"免疫",刷屏的免疫比没有免疫更吵。

五、调参指南与商业服怎么用

调参先看三秒的结构。免伤两秒加攻速一秒是另一条路——前两秒纯粹喘息,最后一秒提速讨刀,两种节奏给两种职业;免伤三秒全免的版本最直白,适合给新手。攻速乘二对三秒是"讨回三十点"的窗口,讨回量要贴着发作前挨掉的血量设计——讨得回,玩家觉得志气有灵;讨不回,它就只是一条多出来的血。旗标的重置时机必须挂场景清空,挂在死亡复活上的版本,复活立刻又能骗死一次,机制变成一次性复活币。常见坑三个:真死亡(坠落、即死)绕过扣血入口直接触发,志气拦不住;攻速层没卸,志气散了刀还是快的;发作瞬间扣血入口被连击二次调用,免伤层没挂上就扣成了负血。

商业服里不屈志是"最后一张牌"的付费点:志气的发作特效做成品级——铜志气白光、金志气红光,死亡边缘那一眼是全游戏曝光率最高的广告位。副本里它是灭团统计的改写者:会留志气的队和不会留的队,灭团率差一半,攻略帖的标题都替你想好了。变体做成志气传承:志气发作时倒下的队友站起来一半——把个人保命做成团队翻盘,机制的地位再上一档。还有一档是志气可见化:队友头顶的志气条对全队公开,救谁让谁、一目了然,团队决策多了一层参考。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做保命系的同学:一次性机制卖的是"合同精神"——发作那一刻所有的账当帧结清,玩家的下一次冲锋才敢押上这条命。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

剑环:三柄飞剑绕着转,贴身就挨削

【游戏功能】 安全巡检扫出一笔可疑的挂账:玩家的"周围单位结算"列表里,同一只怪每零点八秒出现一次,可战斗记录里玩家根本没出…

2026-10-01 05:08 996 技术组
进阶实战游戏功能

困灵阵:画个圈关住它,出圈的腿会疼

【游戏功能】 困灵阵的全机制就一句:阵落在它脚下,八秒里它就是圈中之物——敢跨出圈沿,一步吃十五还被弹回去,你在圈外安安稳稳…

2026-10-01 05:08 996 技术组
进阶实战游戏功能

火油阵:先泼油再点灯,两步烧一条线

【游戏功能】 先泼油还是先点火?这道题答错的代价是一地白烧的火——灯点在空地上,怪还没踩上来,四秒的火一点没沾着它的毛。火油…

2026-10-01 05:08 996 技术组
进阶实战游戏功能

冰壁垒:一堵墙横在地上,谁也过不去

【游戏功能】 寻路组收到一笔诡异的工单:怪物巡逻到某个坐标段必卡三秒,像踩了看不见的门槛——排查两小时,发现那段路上有一个上…

2026-10-01 05:08 996 技术组
进阶实战游戏功能

双桩雷阵:两桩立起来,桩间就是雷区

【游戏功能】 local a, b = math.min(x1, x2), math.max(x1, x2) ——一行把两根…

2026-10-01 05:08 996 技术组
进阶实战游戏功能

镇魂碑:立碑镇住它,大招读不完

【游戏功能】 测试组报过一口邪门的单:头目的读条明明被打断过,技能照样出了膛——查了半天不是打断失效,是打断只"清了"不"冻…

2026-10-01 05:08 996 技术组