Unity游戏AI工具踩坑与实践经验

Unity游戏AI工具踩坑与实践经验

去年开始折腾Unity的AI工具,从2D寻路到智能NPC,踩了不少坑。记录一下用过的工具和实战经验。

Unity官方NavMesh只支持3D,2D游戏得用NavMeshPlus这个插件。

安装

通过Package Manager安装:

1
2
Window → Package Manager → Add package from git URL
https://github.com/h8man/NavMeshPlus.git

基础配置

四步走:

  1. 碰撞层配置:TileMap碰撞层加NavMeshModifier,勾选OverrideArea选NotWalkable
  2. 地面层配置:TileMap地面层加NavMeshModifier,勾选OverrideArea选Walkable
  3. 创建NavMesh物体:空物体加Navigation Surface和Navigation CollectSources2D,点击”Rotate Surface to XY”
  4. 烘焙导航网格:调整Layers层级,设置UseGeometry,点Bake

寻路代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
using UnityEngine.AI;

public class AgentController : MonoBehaviour
{
public NavMeshAgent navMeshAgent;

private void Start()
{
// 2D游戏必须锁Z轴和旋转
navMeshAgent.updateUpAxis = false;
navMeshAgent.updateRotation = false;

// 设置目标
navMeshAgent.SetDestination(new Vector3(5, 5, 0));
}
}

运行时烘焙

程序化生成的地图需要动态烘焙:

1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;
using UnityEngine.AI;

public class RuntimeNavMeshBaker : MonoBehaviour
{
public NavMeshSurface Surface2D;

void Start()
{
Surface2D.BuildNavMeshAsync(); // 异步烘焙不卡帧
}
}

Y轴卡住问题

NavMeshPlus有个坑,Agent在Y轴上会卡住。

解决方案1:加个微小偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static float agentDrift = 0.0001f;

void SetDestination(GameObject target)
{
if (Mathf.Abs(transform.position.x - target.transform.position.x) < agentDrift)
{
var driftPos = target.transform.position + new Vector3(agentDrift, 0f, 0f);
agent.SetDestination(driftPos);
}
else
{
agent.SetDestination(target.transform.position);
}
}

解决方案2:导航网格倾斜89.98度(官方推荐)

智能NPC工具对比

Inworld AI

功能挺全的:

  • 自然语言创建AI角色
  • 自定义性格、记忆、知识库
  • 多模态交互(对话、动作、情绪)
  • 无代码集成

集成代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class InworldNPC : MonoBehaviour
{
private InworldCharacter character;

void Start()
{
character = GetComponent<InworldCharacter>();
character.SendText("Hello! What can you tell me about this place?");
}

public void OnCharacterSpeaks(InworldPacket packet)
{
Debug.Log($"NPC: {packet.text}");
}
}

缺点:国内网络不稳定,延迟高。

Convai

支持语音和文字对话,有动作执行能力和背景故事系统。但文档比较少,上手难度大。

Charisma叙事AI

专门做叙事的分支,动态故事线生成做得不错,适合剧情向游戏。

程序化内容生成

Atlas 3D资产生成

文本生成3D模型,概念性API大概长这样:

1
2
3
4
5
public async void GenerateAsset(string description)
{
var asset = await AtlasAPI.GenerateAsset(description);
Instantiate(asset, transform.position, Quaternion.identity);
}

实际用下来生成的模型面数太高,需要手动减面才能用。

Layer AI风格化生成

上传3-5张参考图,可以批量生成同风格资源。流程:

  1. 上传参考图
  2. 选择输出类型(角色/场景/道具)
  3. 输入描述文字
  4. 批量生成
  5. 导入Unity

效果还行,但风格一致性有时候会有偏差。

Leonardo AI纹理生成

Unity Asset Store有插件,选中模型点生成就行。自动生成PBR纹理,省了不少美术工作量。

Polyhive 3D纹理

通过文本指令生成纹理,比如输入”中世纪城堡石墙纹理,苔藓覆盖”,自动生成。比传统手绘快很多。

开发工具链

VSCode + Unity配置

推荐插件:

插件 版本 功能
C# v1.24.1 代码提示
C# Dev Kit v0.3.21 调试支持
Unity v0.9.0 Unity集成
Unity Code Snippets v2.2.5 代码片段
Unity Tools v1.2.12 工具集

Unity Package也要装:

1
2
Visual Studio Code Editor: 1.2.5
Visual Studio Editor: 2.0.20

关联设置:

1
2
3
4
Edit → Preferences → External Tools
→ External Script Editor → Browse
→ 选择VSCode安装目录\Code.exe
→ 点击 Regenerate Project Files

CodeGeeX2代码生成

清华出的代码生成模型,本地部署:

1
2
3
4
5
6
7
conda create -n CodeGeeX2 python=3.10 -y
conda activate CodeGeeX2
pip3 install torch --index-url https://download.pytorch.org/whl/cu118

git clone https://github.com/THUDM/CodeGeeX2.git
cd CodeGeeX2
pip install -r requirements.txt

VSCode装CodeGeeX插件就能用。代码补全效果还行,但有时候生成的代码有bug,需要人工检查。

Modl.ai自动化测试

AI自动跑关卡找bug,能检测崩溃和性能问题。但配置复杂,小项目用不上。

2D游戏开发

Tilemap工作流

层级结构:

1
2
3
4
Grid (父物体)
├── Ground (Tilemap) - 地面层
├── Obstacles (Tilemap) - 障碍物层
└── Details (Tilemap) - 细节层

碰撞设置:

1
2
3
4
障碍物Tilemap添加组件:
1. Tilemap Collider 2D
2. Rigidbody 2D (Static)
3. Composite Collider 2D (可选,优化性能)

Sprite资源转换

从Cocos转Unity经常遇到plist文件问题。

TexturePacker方式:

  1. TextureUnpacker分割plist图片
  2. 分割图导入TexturePacker
  3. Framework选Unity - Texture2D sprite sheet
  4. Publish sprite sheet
  5. Unity装TexturePacker Importer插件

Aseprite方式(推荐):

  1. 分割plist图片集
  2. 导入Aseprite
  3. File → Export Sprite Sheet
  4. Sheet Type: By Rows
  5. Constraints: Fixed Columns (如6列)
  6. 导出

AI驱动的游戏设计

斯坦福小镇模拟器思路

智能体决策流程:

  1. Perceive(感知):获取周围环境信息
  2. Retrieve(检索):从记忆中提取相关信息
  3. Plan(规划):制定行动计划
  4. Reflect(反思):根据记忆生成新想法
  5. Execute(执行):执行具体动作

记忆系统评分公式:

1
Score = α*Recency + β*Importance + γ*Relevance
  • Recency:新鲜度,随时间衰减
  • Importance:重要度,1-10评分
  • Relevance:关联度,向量余弦相似度

AI叙事系统

参考Hidden Door的实现思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AINarrativeSystem : MonoBehaviour
{
public string sourceMaterial; // 训练素材
public string currentPlot; // 当前剧情

public async void GenerateStoryBeat(string playerAction)
{
var prompt = $"""
Based on {sourceMaterial} universe,
Player action: {playerAction}
Current plot: {currentPlot}
Generate the next story beat:
""";

var nextBeat = await LLM.Generate(prompt);
UpdatePlot(nextBeat);
}
}

AI副驾驶

建筑助手和战斗助手的概念:

1
2
3
4
5
6
7
8
public class AICopilot : MonoBehaviour
{
// 分析玩家意图,提供逐步指导
public void SuggestBuild(string playerIntent) { }

// 分析战场形势,建议战术动作
public void CombatAssist(CombatSituation situation) { }
}

完整的2D RPG AI系统

NPC控制器结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class SmartNPC : MonoBehaviour
{
public NavMeshAgent agent;
public NPCMemory memory;
public NPCPersonality personality;
public DialogueSystem dialogue;
public EmotionDisplay emotionDisplay;

void Update()
{
var perception = PerceiveEnvironment();
memory.Store(perception);
var action = DecideAction();
ExecuteAction(action);
}

void ExecuteAction(NPCAction action)
{
switch (action.type)
{
case ActionType.Move:
agent.SetDestination(action.targetPosition);
break;
case ActionType.Talk:
dialogue.StartDialogue(action.target);
break;
case ActionType.Emote:
emotionDisplay.Show(action.emotion);
break;
}
}
}

对话系统数据结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[System.Serializable]
public class DialogueNode
{
public string npcText;
public List<DialogueOption> playerOptions;
public Emotion npcEmotion;
}

[System.Serializable]
public class DialogueOption
{
public string optionText;
public DialogueNode nextNode;
public int relationshipImpact;
}

性能优化

AI系统优化

优化项 方法 收益
路径计算 异步烘焙 减少卡顿
感知更新 降低频率 减少CPU占用
决策系统 状态机+行为树 提高响应速度
内存管理 对象池 减少GC

寻路优化

限制路径更新频率:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class OptimizedAgent : MonoBehaviour
{
public float pathUpdateInterval = 0.5f;
private float lastPathUpdate;

void Update()
{
if (Time.time - lastPathUpdate > pathUpdateInterval)
{
UpdatePath();
lastPathUpdate = Time.time;
}
}

void UpdatePath()
{
// 目标移动足够距离才重新计算
if (Vector3.Distance(agent.destination, target.position) > 1.0f)
{
agent.SetDestination(target.position);
}
}
}

Unity的AI工具生态发展挺快,但实际项目中能直接用的不多。NavMeshPlus算是刚需,Inworld AI效果可以但网络问题大,代码生成工具能提高效率但需要人工review。建议小项目先用成熟的方案,等AI工具更成熟了再上复杂的。