You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Roblox塔防游戏如何实现塔攻击特效及僵尸免疫脚本逻辑

Roblox塔防特殊攻击效果与僵尸免疫实现方案

一、先搭好可扩展的配置表

别上来就写逻辑,先把所有可变参数抽成ModuleScript丢ServerStorage,后期改数值、加新内容不用翻核心逻辑。

  • 状态效果配置表(命名StatusEffectConfig):统一定义所有特殊效果的参数,基础结构参考:
return {
    Freeze = {
        Duration = 2, -- 效果持续时间(秒)
        SlowPercent = 1, -- 减速比例,1即100%减速也就是冻结
        TickDamage = 0, -- 每段持续伤害值
        TickInterval = 0, -- 伤害触发间隔
        StackRule = "Refresh" -- 叠层规则:Refresh刷新持续时间/Add叠加层数/Multiply乘算数值/Ignore不叠加
    },
    Slow = {
        Duration = 3,
        SlowPercent = 0.5,
        TickDamage = 0,
        TickInterval = 0,
        StackRule = "Multiply"
    },
    Poison = {
        Duration = 5,
        SlowPercent = 0,
        TickDamage = 8,
        TickInterval = 1,
        StackRule = "Add"
    }
}
  • 僵尸属性配置表(命名ZombieConfig):每个僵尸类型单独配置免疫列表,不用在逻辑里写硬编码判断:
return {
    NormalZombie = {
        BaseSpeed = 16,
        BaseHp = 100,
        ImmuneStatus = {} -- 无任何效果免疫
    },
    IceResistZombie = {
        BaseSpeed = 14,
        BaseHp = 180,
        ImmuneStatus = {Freeze = true} -- 免疫冻结效果,吃减速和中毒
    },
    ArmorBoss = {
        BaseSpeed = 12,
        BaseHp = 2000,
        ImmuneStatus = {Freeze = true, Slow = true} -- 免疫冻结、减速,仅吃中毒伤害
    }
}

二、核心逻辑实现

所有僵尸生成时,往模型里塞一个StatusManager脚本,所有效果的添加、移除、数值计算、免疫判断全走这个脚本。塔、子弹只负责传递“要给这个僵尸加XX效果”的信号,不许直接改僵尸的速度、血量属性,避免多效果冲突。

命中触发流程

  1. 塔/子弹检测到命中僵尸时,获取僵尸模型上的StatusManager,调用它对外暴露的AddStatus方法,传入效果ID、塔的攻击参数即可,不用管后续处理。
  2. StatusManager收到加效果的请求后,第一步先查当前僵尸对应配置里的ImmuneStatus表,如果对应效果标记为true,直接终止后续逻辑,需要做反馈的话可以在这一步触发免疫的粒子、飘字提示。
  3. 免疫校验通过后,按照效果配置的叠层规则处理:如果是刷新持续时间的效果(比如冻结),就把之前的同名效果定时器取消重新计时;如果是叠加层数的效果(比如中毒),就给当前层数+1;如果是乘算的效果(比如减速),就把减速系数乘进去。
  4. 效果生效期间分类处理逻辑:
    • 冻结/减速类效果:不要每次改速度就直接赋值,写一个统一的UpdateSpeed方法,遍历当前所有生效的移动类效果,冻结优先级最高,只要有冻结效果存在速度直接设为0;没有冻结的话按照叠层规则算总减速比例,乘以僵尸生成时存好的原始基础速度得到当前应该的WalkSpeed赋值,避免多个减速效果互相覆盖。
    • 中毒类持续伤害效果:按照配置的Tick间隔开定时器扣血,叠层的话每层伤害单独计算,持续时间到了就对应减层,层数归零时停止定时器、移除中毒特效。
  5. 效果持续时间到了之后,从生效列表里移除对应效果,重新调用UpdateSpeed计算当前速度,清理绑定的粒子、定时器。

核心代码片段参考

-- 挂载在僵尸模型下的StatusManager脚本
local StatusEffectConfig = require(game.ServerStorage.StatusEffectConfig)
local ZombieConfig = require(game.ServerStorage.ZombieConfig)
local model = script.Parent
local humanoid = model:WaitForChild("Humanoid")
local zombieType = model:GetAttribute("ZombieType")
local zombieData = ZombieConfig[zombieType]
local originalSpeed = zombieData.BaseSpeed -- 生成时直接读配置的基础速度,不会存错
local activeEffects = {} -- 存储所有生效中的效果

-- 对外暴露的加效果接口
function AddStatus(effectId)
    -- 第一步:免疫判断
    if zombieData.ImmuneStatus[effectId] then return end
    local effectConf = StatusEffectConfig[effectId]
    -- 第二步:处理叠层逻辑
    if activeEffects[effectId] then
        if effectConf.StackRule == "Refresh" then
            task.cancel(activeEffects[effectId].cancelToken)
        elseif effectConf.StackRule == "Ignore" then
            return
        end
    end
    -- 第三步:启动效果
    local cancelToken = task.spawn(function()
        -- 初始化:挂对应特效、启动伤害tick
        UpdateSpeed()
        -- 中毒持续伤害逻辑示例
        if effectConf.TickDamage > 0 then
            while task.wait(effectConf.TickInterval) do
                humanoid:TakeDamage(effectConf.TickDamage)
            end
        end
        -- 等待效果持续结束
        task.wait(effectConf.Duration)
        -- 清理效果
        activeEffects[effectId] = nil
        UpdateSpeed()
        -- 删除特效、停止相关逻辑
    end)
    activeEffects[effectId] = {conf = effectConf, cancelToken = cancelToken}
end

-- 统一计算移动速度,解决多效果冲突问题
function UpdateSpeed()
    local totalSlowMulti = 1
    local isFrozen = false
    for _, effect in activeEffects do
        if effect.conf.SlowPercent >= 1 then
            isFrozen = true
            break
        end
        if effect.conf.StackRule == "Multiply" then
            totalSlowMulti *= (1 - effect.conf.SlowPercent)
        end
    end
    humanoid.WalkSpeed = isFrozen and 0 or originalSpeed * totalSlowMulti
end

-- 僵尸死亡时清理所有效果,避免内存泄漏
humanoid.Died:Connect(function()
    for _, effect in activeEffects do
        task.cancel(effect.cancelToken)
    end
    table.clear(activeEffects)
end)

三、实际开发踩过的坑

  • 别图省事在子弹、塔的脚本里直接改僵尸的WalkSpeed,我第一次做的时候就这么写,结果两个塔同时打一个僵尸,一个塔的冻结时间到了直接把速度改回默认值,另一个塔刚上的3秒减速直接失效,查了俩小时才定位到问题,所有属性修改必须走StatusManager统一计算。
  • 原始速度别在第一次触发效果的时候存,一定要在僵尸刚生成、还没吃任何效果的时候读配置存好,不然减速效果结束还原速度的时候会越算越低。
  • 僵尸死亡、对象池回收的时候一定要把所有生效效果的task全部取消,不然后台跑空引用报错,堆多了还会掉帧。
  • 免疫规则千万别硬编码写在逻辑里,比如别写if zombie.Name == "IceZombie" then return end,后面加新僵尸、改免疫规则的时候要翻遍所有脚本找判断分支,漏一个就出bug,全走配置表改起来只需要动一行。

内容的提问来源于stack exchange,提问作者Amogus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:09:11