ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

从0到1开发goa/goap自定义Action:以ChopTreeAction为例的完整教程

2026/8/7 15:52:19 拓冰建站 浏览量
从0到1开发goa/goap自定义Action:以ChopTreeAction为例的完整教程 从0到1开发goa/goap自定义Action以ChopTreeAction为例的完整教程【免费下载链接】goapGoal Oriented Action Planning AI in Unity项目地址: https://gitcode.com/gh_mirrors/goa/goapgoa/goap是一个基于Unity的Goal Oriented Action PlanningGOAPAI系统它允许开发者为游戏角色创建智能决策逻辑。本文将以ChopTreeAction为例详细介绍如何从零开始开发自定义Action帮助新手快速掌握GOAP系统的核心开发技能。什么是GOAP ActionGOAP Action是GOAP系统的核心组成部分它定义了智能体可以执行的具体行为。每个Action包含前置条件、执行效果、目标对象和执行逻辑等关键要素。在goa/goap项目中所有Action都继承自抽象基类GoapAction该类位于Assets/Standard Assets/Scripts/AI/GOAP/GoapAction.cs。GoapAction基类定义了以下必须实现的抽象方法reset()重置Action状态isDone()检查Action是否完成checkProceduralPrecondition()检查过程性前置条件perform()执行Action逻辑requiresInRange()是否需要靠近目标对象开发ChopTreeAction的完整步骤1. 创建Action类并继承GoapAction首先创建一个名为ChopTreeAction的类并继承GoapAction。在goa/goap项目中所有自定义Action都存放在Assets/Standard Assets/Scripts/GameData/Actions/目录下。public class ChopTreeAction : GoapAction { // 实现抽象方法和自定义逻辑 }2. 定义Action的状态变量在ChopTreeAction中我们需要定义一些状态变量来跟踪砍树过程private bool chopped false; private TreeComponent targetTree; // 目标树组件 private float startTime 0; public float workDuration 2; // 砍树所需时间秒3. 实现构造函数和前置条件/效果在构造函数中我们需要设置Action的前置条件和执行效果。对于砍树动作前置条件是拥有工具且没有木材执行效果是获得木材public ChopTreeAction() { addPrecondition(hasTool, true); // 需要工具 addPrecondition(hasLogs, false); // 没有木材 addEffect(hasLogs, true); // 获得木材 }4. 实现reset()方法reset()方法用于重置Action的状态在每次Action被规划时都会调用public override void reset() { chopped false; targetTree null; startTime 0; }5. 实现isDone()方法isDone()方法检查Action是否完成这里我们通过chopped变量来判断public override bool isDone() { return chopped; }6. 实现requiresInRange()方法砍树动作需要靠近树木因此requiresInRange()应返回truepublic override bool requiresInRange() { return true; // 需要靠近树木 }7. 实现checkProceduralPrecondition()方法该方法用于查找合适的目标对象这里是树木。我们需要找到距离智能体最近的树木public override bool checkProceduralPrecondition(GameObject agent) { // 查找所有树木组件 TreeComponent[] trees (TreeComponent[])UnityEngine.GameObject.FindObjectsOfType(typeof(TreeComponent)); TreeComponent closest null; float closestDist 0; foreach (TreeComponent tree in trees) { if (closest null) { closest tree; closestDist (tree.gameObject.transform.position - agent.transform.position).magnitude; } else { float dist (tree.gameObject.transform.position - agent.transform.position).magnitude; if (dist closestDist) { closest tree; closestDist dist; } } } if (closest null) return false; targetTree closest; target targetTree.gameObject; return closest ! null; }8. 实现perform()方法perform()方法包含Action的核心执行逻辑。在这里我们处理砍树过程、获取木材以及工具损耗public override bool perform(GameObject agent) { if (startTime 0) startTime Time.time; if (Time.time - startTime workDuration) { // 完成砍树获取木材 BackpackComponent backpack (BackpackComponent)agent.GetComponent(typeof(BackpackComponent)); backpack.numLogs 1; chopped true; // 使用工具并检查工具是否损坏 ToolComponent tool backpack.tool.GetComponent(typeof(ToolComponent)) as ToolComponent; tool.use(0.34f); if (tool.destroyed()) { Destroy(backpack.tool); backpack.tool null; } } return true; }将自定义Action添加到智能体要让智能体能够使用新创建的ChopTreeAction需要将其添加到相应的智能体组件中。以Logger伐木工人为例在Assets/Standard Assets/Scripts/GameData/Labourers/Logger.cs中ChopTreeAction被用于实现伐木目标。自定义Action开发最佳实践保持单一职责每个Action应只完成一个具体任务如砍树、采矿、锻造等合理设置前置条件和效果确保条件和效果的逻辑一致性这直接影响GOAP规划器的决策优化目标选择在checkProceduralPrecondition()中高效查找目标避免性能问题处理资源消耗如工具损耗、时间成本等使AI行为更真实状态重置在reset()方法中确保所有状态变量都被正确重置总结通过本文的教程你已经了解了如何基于goa/goap项目开发自定义Action。从继承GoapAction基类到实现各种抽象方法再到定义具体的执行逻辑每个步骤都至关重要。掌握Action开发是构建复杂GOAP AI系统的基础希望这个以ChopTreeAction为例的教程能帮助你快速上手goa/goap的开发。现在你可以尝试开发其他类型的Action如采矿MineOreAction、锻造工具ForgeToolAction等这些Action都可以在Assets/Standard Assets/Scripts/GameData/Actions/目录下找到参考实现。【免费下载链接】goapGoal Oriented Action Planning AI in Unity项目地址: https://gitcode.com/gh_mirrors/goa/goap创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考