在这里插入图片描述

在这里插入图片描述

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:
掘金、知乎、CSDN、简书
创作特点:
实战导向、源码拆解、少空谈多落地
文章状态:
长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”

持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱

引言

很多开发者第一次给鸿蒙游戏加 NPC 时,都会这样写:

if (playerNear) {
  attack()
}

或者:

if (hp < 30) {
  runAway()
}

刚开始感觉没问题:

能跑
能打
能追人

但随着游戏复杂度增加:

巡逻
追击
攻击
释放技能
逃跑
求援
Boss机制

很快就会出现一个问题:

if-else 地狱。

代码可能变成:

if (playerNear) {

  if (hp > 50) {

    if (skillReady) {
      castSkill()
    } else {
      attack()
    }

  } else {

    if (friendNear) {
      callHelp()
    } else {
      runAway()
    }

  }

}

几个月后连自己都不敢改,很多人会觉得:

是不是 AI 太复杂了?

其实不是,问题在于:

你在用条件判断实现决策系统。

而现代游戏普遍采用:

Behavior Tree
(行为树)

来驱动 NPC。

一、什么是行为树?

先看一个最简单的 NPC,需求:

发现玩家
↓
攻击玩家

传统写法:

if (canSeePlayer()) {
  attack()
}

没问题,但增加需求:

发现玩家
↓
距离近
↓
攻击

距离远
↓
追击

逻辑开始复杂,行为树则表示为:

发现玩家?
      ↓
   是
      ↓
距离是否足够?
    ↓      ↓
   是      否
    ↓       ↓
 攻击     追击

本质上:

行为树是一种可视化决策流程。

二、为什么游戏都在用行为树?

因为 NPC 本质上就是:

不断决策

例如,怪物:

巡逻
发现敌人
追击
攻击
逃跑

Boss:

一阶段
二阶段
狂暴阶段
释放技能
召唤小怪

这些本质都是:状态选择问题,行为树非常适合处理。

三、行为树的三大节点

最常见的是:

Selector
Sequence
Action

Selector(选择器)

意思:

从左到右尝试
成功一个就结束

例如:

攻击
 ↓失败
追击
 ↓失败
巡逻

表现:

优先攻击
其次追击
最后巡逻

Sequence(顺序器)

意思:

全部成功才算成功

例如:

发现玩家
 ↓
接近玩家
 ↓
攻击

任何一步失败:

整个流程失败

Action(动作节点)

真正执行行为,例如:

Attack
Move
Patrol
RunAway

四、设计一个简单 NPC

需求:

发现玩家
↓
攻击

否则
↓
巡逻

行为树:

Selector
├── AttackPlayer
└── Patrol

对应结构:

root = Selector(
  AttackPlayer(),
  Patrol()
)

五、定义行为树节点

基础接口:

enum NodeStatus {
  Success,
  Failure,
  Running
}

interface BTNode {
  tick(): NodeStatus
}

所有节点统一:

tick()

驱动。

六、实现 Action 节点

巡逻:

class PatrolNode implements BTNode {

  tick(): NodeStatus {

    console.info('Patrol')

    return NodeStatus.Success
  }

}

攻击:

class AttackNode implements BTNode {

  tick(): NodeStatus {

    console.info('Attack')

    return NodeStatus.Success
  }

}

七、实现 Selector

核心逻辑:

class SelectorNode implements BTNode {

  constructor(
    private children: BTNode[]
  ) {}

  tick(): NodeStatus {

    for (const node of this.children) {

      const result = node.tick()

      if (
        result === NodeStatus.Success
      ) {
        return result
      }

    }

    return NodeStatus.Failure
  }

}

作用:

优先执行最重要行为

八、加入条件节点

例如:

发现玩家?

判断,实现:

class SeePlayerNode implements BTNode {

  constructor(
    private npc: NPC
  ) {}

  tick(): NodeStatus {

    return this.npc.canSeePlayer()
      ? NodeStatus.Success
      : NodeStatus.Failure
  }

}

九、实现追击逻辑

需求:

发现玩家
↓
追击
↓
攻击

行为树:

Sequence
├── SeePlayer
├── MoveToPlayer
└── Attack

代码:

const combatTree =
  new SequenceNode([
    new SeePlayerNode(npc),
    new MoveNode(npc),
    new AttackNode(npc)
  ])

十、AISystem 驱动行为树

前面我们讲过:

Store
System
HUD

架构,行为树应该属于:

AISystem

而不是:

UI

例如:

class AISystem {

  update(npc: NPC) {

    npc.behaviorTree.tick()

  }

}

十一、与 Store 结合

NPC状态:

class NPCStore {

  hp = 100

  targetId = 0

  position = {
    x: 0,
    y: 0
  }

}

行为树读取:Store 决策。

然后:

AISystem

修改:

Store

状态,形成:

Store
 ↓
BehaviorTree
 ↓
AISystem
 ↓
Store

闭环。

十二、Boss 行为树实战

Boss需求:

HP > 50%
普通攻击

HP < 50%
释放大招

HP < 20%
狂暴模式

行为树:

Selector
├── RageMode
├── UltimateSkill
└── NormalAttack

代码:

Selector(
  RageNode(),
  UltimateNode(),
  AttackNode()
)

结构非常清晰。

十三、为什么行为树比 if-else 更强?

传统:

if()
  if()
    if()
      if()

最终:

无法维护

行为树:

节点化
可组合
可扩展

增加新行为:

SkillNode

插入即可,无需重写全部逻辑。

十四、行为树与多端同步

前面我们讲:

Store一致
System一致

才能实现:

多端一致性

行为树天然符合,因为:

输入一致
↓
行为树一致
↓
决策一致
↓
状态一致

例如:

手机NPC
PC NPC

执行同一行为树,结果相同。

十五、未来升级:行为树 + AI Agent

未来 NPC 不再只是:

固定规则

而是:

行为树
+
大模型

例如:

行为树
负责框架

LLM
负责决策

结构:

Selector
 ↓
AskLLM()
 ↓
Attack
Move
Trade
Talk

NPC 会变得更加智能。

十六、一个关键认知升级

初学者认为:

AI = if-else

进阶开发者认为:

AI = 行为树

而大型项目最终理解:

行为树不是 AI,而是管理 AI 决策复杂度的架构。

因为真正的问题从来不是:

NPC会不会攻击

而是:

当NPC拥有100种行为时
系统还能不能维护

总结

鸿蒙游戏中的 AI NPC 推荐架构:

Store
  ↓
BehaviorTree
  ↓
AISystem
  ↓
Store

核心节点:

Selector
Sequence
Action

核心优势:

逻辑清晰
可视化
易扩展
易测试
支持多端同步

如果用一句话总结:

行为树的本质,不是让 NPC 更聪明,而是让复杂 AI 行为变得可管理、可组合、可扩展。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐