在 Roblox 中打造生动逼真的敌人——无论是生存恐慌中的追踪怪、RPG 副本机制 Boss,还是战术射击小队——最忌讳混乱的面条代码。将上百行 if-else 堆砌在单个脚本中,极易导致寻路死锁、逻辑冲突以及严重的服务器帧率雪崩。
工业级游戏开发通用方案为:宏观行为依赖有限状态机(FSM),微观战斗战术交由行为树(Behavior Trees)。本指南深入剖析黑板(Blackboard)数据总线、视锥(FOV)射线检测、仇恨机制,以及基于 AI LOD 的服务器 Tick 分帧调度方案。
根据敌人复杂度与交互密度科学选型:
在极低 CPU 负载下赋予 NPC 拟真的空间视觉感知:
-- Modular Finite State Machine for Roblox NPC
local StateMachine = {}
StateMachine.__index = StateMachine
function StateMachine.new(npcInstance, states, initialState)
local self = setmetatable({}, StateMachine)
self.NPC = npcInstance
self.States = states
self.CurrentState = nil
self.Blackboard = {
Target = nil,
LastSeenPos = nil,
Health = 100,
PatrolPoints = {}
}
self:ChangeState(initialState)
return self
end
function StateMachine:ChangeState(newStateName)
if self.CurrentState and self.States[self.CurrentState].Exit then
self.States[self.CurrentState]:Exit(self.NPC, self.Blackboard)
end
self.CurrentState = newStateName
if self.States[newStateName] and self.States[newStateName].Enter then
self.States[newStateName]:Enter(self.NPC, self.Blackboard)
end
end
function StateMachine:Update(dt)
if self.CurrentState and self.States[self.CurrentState].Update then
local nextState = self.States[self.CurrentState]:Update(self.NPC, self.Blackboard, dt)
if nextState and nextState ~= self.CurrentState then
self:ChangeState(nextState)
end
end
end
return StateMachine
构建清晰的分层优先级决策链路:
保证 100+ 敌人同屏活动时服务器稳定维持 60 FPS:
Instance.new 与 Destroy。预热 NPC 对象池,通过切换透明度与 CFrame 实现怪物复用。因为所有怪物都在 60Hz 帧率下盲目执行射线检测与路径运算。必须引入 AI LOD,分帧摊薄感知频率。
行为树具备极强的模块插拔性,新增技能与行为逻辑无需修改错综复杂的状态连线,彻底规避状态爆炸。
从 NPC 头部向玩家躯干投射射线,通过 RaycastResult 判定是否有墙壁掩体阻断视线通道。
绝不能!所有寻路决策与伤害结算必须保留在服务端,防止外挂篡改数据。客户端仅负责动作与位移表现。