AI门户, 中国人工智能行业资讯平台--AI门户网
来源:AI门户网     时间:2026/3/25 22:11:14     共 3152 浏览

不知道你有没有过这样的经历:在Unity里好不容易摆好了场景和角色,结果做出来的怪物要么像个木头桩子一样杵在原地,要么就是追起玩家来像个无头苍蝇,要么干脆直接穿墙而过……这游戏体验,简直比新手如何快速涨粉还让人头疼。没错,给游戏里的怪物注入“灵魂”,让它能自己思考、巡逻、追击甚至耍点小聪明,这就是怪物AI要干的事。今天,咱们就抛开那些让人眼晕的复杂术语,用大白话把这套“Unity怪物AI框架”给掰开揉碎了讲明白。

别怕,咱们就从最基础的“状态”说起。

怪物的“心情”:理解有限状态机(FSM)

你可以把怪物的AI想象成它有一套固定的“心情模式”。大多数时候,它心情平静,在属于自己的地盘里漫无目的地溜达,这个心情就叫“巡逻”(Patrol)。突然,它眼角瞥见你了!心情立马切换到“警觉和兴奋”,开始追着你跑,这叫“追击”(Chase)。等它终于跑到你跟前,够得着你了,心情变成“攻击欲望”,挥起爪子或放出技能,这就是“攻击”(Attack)。打了一会儿,你跑远了,它追不上,可能又觉得索然无味,心情慢慢平复,回去继续溜达。

这一套“巡逻->发现你->追击->够着了就攻击->你跑了就放弃”的流程,就是最经典、也最常用的AI框架——有限状态机。它的核心思想特别简单:

*一个时间点,怪物只能有一种“心情”(状态)。

*每种“心情”下,它有自己固定要做的事(比如巡逻时就是来回走,追击时就是朝着玩家位置移动)。

*当满足某个条件时,它的“心情”就会改变(比如“看见玩家”这个条件,触发了从“巡逻”到“追击”的转变)。

在代码里,这通常用一个`switch`语句或者一堆`if-else`就能实现。比如,网上很多教程里你都能看到类似这样的结构:

```csharp

void Update() {

switch(currentMood) { // currentMood 就是当前状态

case Mood.Patrol:

执行巡逻逻辑();

if (看到玩家了) currentMood = Mood.Chase; // 条件触发,切换状态

break;

case Mood.Chase:

执行追击逻辑();

if (玩家进入攻击范围) currentMood = Mood.Attack;

if (玩家跑没影了) currentMood = Mood.Patrol;

break;

case Mood.Attack:

执行攻击逻辑();

break;

}

}

```

看,是不是没那么玄乎了?它就是一套清晰的“如果……就……”的规则集合。

让怪物“动起来”:导航与移动

光有“心情”还不够,怪物得真的能移动才行。这里就要请出Unity的“寻路神器”——NavMesh(导航网格)NavMeshAgent(导航代理)组件。

你可以把NavMesh理解成在地上画好的一张“可通行地图”。你在Unity编辑器里烘焙一下,它就会自动在场景里 walkable 的地面上生成一层看不见的网格,告诉AI:“喂,绿色区域才能走,墙壁和悬崖不能走。”

而NavMeshAgent组件,就是挂在你怪物身上的一个“自动驾驶仪”。你只需要在代码里告诉它一个目标点:

```csharp

agent.SetDestination(玩家.position);

```

它就会自己计算最短路径,绕过障碍,平滑地移动过去。你基本不用操心“怎么绕过那个箱子”这种问题,引擎帮你解决了。这大大降低了AI移动的开发难度。

不过,这里有个新手常踩的坑:别在每帧(Update)里都疯狂设置目标点。如果你的玩家是用`transform.position`直接瞬移的(虽然不推荐),或者你每帧都`SetDestination`,会导致NavMeshAgent不断重新规划路径,可能让怪物抽搐或者卡住。好的做法是隔一段时间(比如0.2秒)更新一次目标,或者确保玩家用物理方式(如`Rigidbody`)移动。

框架的进化:从状态机到更强大的工具

用简单的状态机(FSM)做两三个状态的AI没问题,但状态一多,`switch`语句就会变得又长又乱,像一团理不清的毛线。这时候,我们就需要更有条理的工具。

行为树(Behavior Tree)是更高级、也更可视化的一种选择。它把AI决策做成了一棵“倒长的树”。树的节点分几种类型:

*序列节点:按顺序执行子节点,一个失败了就停止。

*选择节点:挨个尝试子节点,直到有一个成功为止。

*条件节点:判断“玩家是否在视野内?”“血量低于30%吗?”,返回成功或失败。

*动作节点:执行具体行为,比如“移动至某点”、“播放攻击动画”。

行为树的好处是逻辑清晰,易于设计和调试,特别适合做有复杂决策分支的AI(比如是优先逃跑还是吃药,还是呼叫同伴)。市面上也有很多Unity的插件支持用图形化界面拖拽节点来制作行为树。

那么,问题来了:对于刚入门的小白,到底该学状态机还是行为树呢?

我的观点是,毫无疑问,先从状态机(FSM)开始。原因很简单:

1.概念直接:它就是“状态”和“条件”,符合最直观的思维。

2.实现简单:几行代码就能跑起来,立刻看到效果,成就感强。

3.理解基石:几乎所有AI框架底层思想都离不开状态转换,学好了FSM,再看行为树会更容易理解。

4.足够使用:对于很多中小型游戏,一个精心设计的状态机完全够用,没必要过度设计。

先把FSM玩熟,做出一个会巡逻、追击、攻击的怪物,这比你一开始就对着复杂的行为树框架发呆要实在得多。

实战!搭建一个简易怪物AI框架

纸上谈兵终觉浅,我们来勾勒一个极简的框架代码结构,你可以依此扩展:

首先,定义一个管理所有状态的“状态机管理器”。它负责持有当前状态,并在每帧执行当前状态的更新逻辑。

```csharp

public class EnemyAI : MonoBehaviour {

public enum State { Idle, Patrol, Chase, Attack, Flee }

public State currentState;

private NavMeshAgent agent;

public Transform player;

void Start() {

agent = GetComponent();

EnterState(State.Patrol); // 初始状态

}

void Update() {

// 根据当前状态执行不同逻辑

switch(currentState) {

case State.Patrol: UpdatePatrol(); break;

case State.Chase: UpdateChase(); break;

// ... 其他状态

}

}

void EnterState(State newState) {

// 离开旧状态前的清理(可选)

// 切换到新状态

currentState = newState;

// 进入新状态时的初始化(可选)

}

void UpdatePatrol() {

// 1. 移动逻辑:随机或按路径点移动

// 2. 检测逻辑:判断是否发现玩家(可以用物理检测,如OverlapSphere)

// 3. 转换逻辑:如果发现玩家,则 EnterState(State.Chase);

}

// ... 其他状态的具体实现

}

```

其次,把视觉/听觉检测这部分单独抽象出来。比如,在怪物前方放一个扇形或锥形的碰撞体(勾选IsTrigger),当玩家进入这个触发器,就判定为“发现”。更高级点,可以结合射线检测,判断玩家和怪物之间有没有墙壁遮挡。

最后,数据驱动。把怪物的巡逻速度、追击速度、视野范围、攻击距离等参数都做成`public`变量,或者在ScriptableObject中配置。这样你不需要改代码,只需在编辑器里调整数值,就能创造出行为各异的怪物(比如视力好的哨兵、跑得快的突袭者、血厚攻高的坦克)。

小编观点

所以,回到最开始的问题,Unity怪物AI框架难吗?对于新手,它最难的部分可能不是写代码,而是如何把脑子里“这个怪物应该怎么行动”的想法,清晰地翻译成“状态”和“转换条件”。我的建议是,动手前,先在纸上画一画这个怪物的“行为流程图”:它平时干嘛?什么情况下会注意到我?追我时如果遇到障碍怎么办?打不过会跑吗?把这张图画明白了,再动手编码,会顺畅无数倍。

别去追求一步到位搞出个惊天动地的智能AI,就从最简单的“发呆->看见你->走过来”开始。当你看到自己控制的角色被那个傻乎乎的方块怪物追着满屏幕跑时,那种乐趣和成就感,才是驱动你继续深入学习下去的最大动力。记住,所有复杂的系统,都是由一个个简单的“如果…就…”构建起来的。

版权说明:
本网站凡注明“AI门户网 原创”的皆为本站原创文章,如需转载请注明出处!
本网转载皆注明出处,遵循行业规范,如发现作品内容版权或其它问题的,请与我们联系处理!
您可以扫描右侧微信二维码联系我们。
  • 相关主题:
同类资讯
网站首页 关于我们 联系我们 合作联系 会员说明 新闻投稿 隐私协议 网站地图