行为树(Behavior Trees)

这篇具有很好参考价值的文章主要介绍了行为树(Behavior Trees)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

行为树(Behavior Trees)是一种在游戏开发中广泛使用的AI设计模式,主要用于描述AI的行为和决策过程,实现更加智能和自然的游戏AI。它由多个节点组成,每个节点代表一个行为或决策,按照特定的方式连接在一起,形成一个树状结构。
在行为树中,根节点是AI的起点,通过遍历子节点来决策AI的行为。节点有以下三种状态:成功(Success)、失败(Failure)和运行(Running)。前两个通知其父节点其操作是成功还是失败。第三种意味着尚未确定成功或失败,并且该节点仍在运行。下次树被选择时,该节点将再次被选择,此时它将再次有机会成功,失败或继续运行。一般行为树还会携带一个Blackboard,用于存储节点的共享数据。
行为树的节点有以下几种主要原型:

  1. 组合控制节点(Composite):一种将多个子节点组合在一起的节点,用于实现复杂的行为和决策逻辑。主要包括顺序节点(Sequencer)和选择节点(Selector)。顺序节点按顺序依次执行子节点,直到所有子节点都返回成功或者任意一个子节点返回失败为止,当有子节点返回失败则停止不再执行后续子节点。选择节点按照顺序执行子节点,当某个子节点返回成功时,停止执行并返回成功。
    行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树
    行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树

  2. 修饰节点(Decorator):一种特殊的节点,它不执行具体的行为或决策,而是修饰其它节点的行为或决策。主要包括逆变节点(Inverter)和重复节点(Repeater)。逆变节点可以将子节点的结果倒转,比如子节点返回了失败,则这个修饰节点会向上返回成功,以此类推。重复节点重复执行其子节点指定的次数或者一直重复执行,直到其子节点返回成功或者失败。
    行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树
    行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树

  3. 叶节点(Leaf):树的最末端,执行具体行为的节点。

行为树通过模拟树状结构来描述AI的行为和决策过程,使得AI的行为更加灵活、自然和智能。
代码实现
行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    public class BehaviourTree : MonoBehaviour
    {
        private Node root = null;
        private Blackboard blackboard;

        public Node Root
        {
            get
            {
                return root;
            }
            set
            {
                root= value;
            }
        }

        void Start()
        {
            Init();
        }

        void Update()
        {
            if(root!=null&& gameObject!=null)
            {
                root.Evaluate(gameObject.transform,blackboard);
            }
        }

        protected virtual void Init()
        {
            blackboard = new Blackboard();
        }
        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //行为树共享数据
    public class Blackboard
    {
        private Dictionary<string,object> Data;

        public Blackboard()
        {
            Data = new Dictionary<string, object>();
        }

        //获取数据
        public T Get<T>(string key)
        {
            if(Data.ContainsKey(key))
            {
                return (T)Data[key];
            }
            return default;
        }

        //添加数据
        public void Add<T>(string key,T value)
        {
            if(Data.ContainsKey(key))
            {
                Data[key] = value;
            }
            else
            {
                Data.Add(key,value);
            }
        }

        //删除数据
        public void Remove(string key)
        {
            if(Data.ContainsKey(key))
            {
                Data.Remove(key);
            }
            else
            {
                Debug.Log("数据不存在 "+key);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //状态类型
    public enum Status
    {
        Running,    //运行中
        Failure,    // 失败
        Success,    //成功
    }

    //节点基类
    public abstract class Node
    {
        protected Node parent;
        protected Status status;

        Status Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        public Node()
        {
            
        }
        
        //声明节点状态返回方法
        public abstract Status Evaluate(Transform transform,Blackboard blackboard);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //复合节点类
    public abstract class Composite : Node
    {
        //子节点列表
        protected List<Node> children = new List<Node>();
        protected int index;//子节点下标计数
        protected Composite(List<Node> children)
        {
            index = 0;
            foreach(var child in children) 
            {
                this.children.Add(child);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //修饰器节点
    public abstract class Decorator : Node
    {
        //子节点列表
        protected List<Node> children;
        protected Decorator(List<Node> children)
        {
            children = new List<Node>(){};
            foreach(var child in children) 
            {
                this.children.Add(child);
            }
        }
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //选择节点,所有子节点都为失败则失败
    public class Selector : Composite
    {
        
        public Selector(List<Node> children) : base(children)
        {
            
        }

        //所有子节点都为失败则失败
        public override Status Evaluate(Transform transform, Blackboard blackboard)
        {
            if(index>=children.Count)
            {
                index = 0;
                return Status.Success;
            }
            var status = children[index].Evaluate(transform,blackboard);
            switch(status)
            {
                case Status.Success:
                    index = 0;
                    return Status.Success;
                case Status.Failure:
                    index+=1;
                    if(index>=children.Count)
                    {
                        index = 0;
                        return Status.Failure;
                    }
                    return Status.Running;
                case Status.Running:
                    return Status.Running;
                default:
                    return Status.Failure;
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //顺序节点,所有子节点成功才成功
    public class Sequencer : Composite
    {
        public Sequencer(List<Node> children) : base(children)
        {
            
        }

        //所有子节点成功才成功
        public override Status Evaluate(Transform transform, Blackboard blackboard)
        {
            if(index>=children.Count)
            {
                index = 0;
                return Status.Success;
            }
            var status = children[index].Evaluate(transform,blackboard);
            switch(status)
            {
                case Status.Success:
                    index+=1;
                    if(index>=children.Count)
                    {
                        index = 0;
                        return Status.Success;
                    }
                    return Status.Running;
                case Status.Failure:
                    return Status.Failure;
                case Status.Running:
                    return Status.Running;
                default:
                    return Status.Failure;
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    //任务节点,这里会处理对象具体行为逻辑(叶节点)
    public abstract class Task : Node
    {
        
    }
}

简单使用
实现敌人在两点之间巡逻,人物靠近会变红温并停止移动,人物远离时继续巡逻
行为树(Behavior Trees),游戏AI,Unity,游戏开发,行为树

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;
using System.ComponentModel.Design.Serialization;
using System.Linq;

namespace BehaviourTree
{
    public class EnemyBT : BehaviourTree
    {
        Vector3 aPos = new Vector3(4.07999992f,-2.21000004f,-2);
        Vector3 bPos = new Vector3(4.07999992f,1.65999997f,-2)
        protected override void Init()
        {
            //调用基类初始化
            base.Init();
            //创建变红节点
            TurnRed turnRed = new TurnRed();
            //创建巡逻节点
            Patrol patrol = new Patrol(aPos,bPos);
            //创建查找节点
            FindObject findObject = new FindObject();
            //创建侦查节点子节点序列
            Node[] spyChildren = {findObject,turnRed};
            //创建顺序节点用于执行侦查行为
            EnemySequencer enemySequencer = new EnemySequencer(spyChildren.ToList());
            //创建根节点子节点序列
            Node[] selectorChildren = {enemySequencer,patrol};
            //创建选择节点用于处理侦查和巡逻行为
            EnemySelector enemySelector = new EnemySelector(selectorChildren.ToList());
            //将选择节点设置为根节点
            Root = enemySelector;
            
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    public class EnemySelector : Selector
    {
        public EnemySelector(List<Node> children) : base(children)
        {
            
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;

namespace BehaviourTree
{
    public class EnemySequencer : Sequencer
    {
        public EnemySequencer(List<Node> children) : base(children)
        {
    
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;
using DG.Tweening;

namespace BehaviourTree
{
    public class FindObject : Task
    {
        float radius = 5f;
        int layer = 512;
        public override Status Evaluate(Transform transform, Blackboard blackboard)
        {
            Collider2D obj = Physics2D.OverlapCircle(transform.position,radius,layer);
            if(obj!=null)
            {
                return Status.Success;   
            }
            transform.gameObject.GetComponent<SpriteRenderer>().DOColor(Color.white,1);
            return Status.Failure;
        }
    }
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;
using DG.Tweening;

namespace BehaviourTree
{
    //在aPoint和bPoint之间来回移动
    public class Patrol : Task
    {
        Vector3 aPoint;
        Vector3 bPoint;
        float speed = 4f;
        Vector3 target;
        public Patrol(Vector3 aPos,Vector3 bPos)
        {
            aPoint = aPos;
            bPoint = bPos;
            target = aPoint;
        }
        public override Status Evaluate(Transform transform, Blackboard blackboard)
        {
            if(Vector2.Distance(transform.position,target)<0.1f)
            {
                if(target == aPoint)
                {
                    target = bPoint;
                }
                else
                {
                    target = aPoint;
                }
            }
            else
            {
                transform.position = Vector2.MoveTowards(transform.position,target,Time.deltaTime*speed);
            }
            return Status.Success;
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BehaviourTree;
using DG.Tweening;

namespace BehaviourTree
{
    //变红
    public class TurnRed : Task
    {
        Vector3 bPoint;
        public override Status Evaluate(Transform transform, Blackboard blackboard)
        {
            transform.gameObject.GetComponent<SpriteRenderer>().DOColor(Color.red,1);
            return Status.Success;
        }
    }
}

总结
作为常用的AI设计模式,行为树相比有限状态机在实现复杂AI上更有优势。行为树可以模仿人类思维过程,先做什么,再在做什么。并且行为树拥有多种控制节点和修饰节点,节点之间相互组合可实现多种效果。文章来源地址https://www.toymoban.com/news/detail-803029.html

到了这里,关于行为树(Behavior Trees)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity】AI实战应用——Unity接入GPT和对游戏开发实际应用的展望

    GPT for unity插件地址: GitHub - sunsvip/ChatGPTForUnity: ChatGPT for unity 用法: 打开Unity PackageManager界面. Add package from git URL 粘贴插件地址添加 https://github.com/sunsvip/ChatGPTForUnity.git ———————————————————————————————————— 几个资本大佬花钱让一群

    2024年02月08日
    浏览(41)
  • 【Unity】AI实战应用——Unity接入ChatGPT和对游戏开发实际应用的展望

    GPT for unity插件地址: GitHub - sunsvip/ChatGPTForUnity: ChatGPT for unity 用法: 打开Unity PackageManager界面. Add package from git URL 粘贴插件地址添加 https://github.com/sunsvip/ChatGPTForUnity.git ———————————————————————————————————— 几个资本大佬花钱让一群

    2023年04月08日
    浏览(47)
  • 游戏AI行为决策——HTN(分层任务网络)

    Hierarchical Task Network(分层任务网络),简称HTN,与行为树、GOAP一样,也是一种行为决策方法。在《地平线:零之曙光》、《变形金刚:塞伯坦的陨落》中都有用它来制作游戏敌人的AI (我一个都没玩过捏 。比起其它行为决策方法,HTN有个十分鲜明的特点: 推演 。 HTN允许我

    2024年02月02日
    浏览(62)
  • 公开 学生课堂行为数据集 SCB-Dataset Student Classroom Behavior dataset

    公开 学生课堂行为数据集 SCB-Dataset Student Classroom Behavior dataset b站:https://www.bilibili.com/video/BV1Fv4y1H7sa/ arxiv: https://arxiv.org/pdf/2304.02488.pdf github: https://github.com/Whiffe/SCB-dataset 百度云:https://pan.baidu.com/s/1y3lGEYd-I-jxZKyAyw4MPw?pwd=zdbg extraction code: ZDBG

    2024年02月12日
    浏览(39)
  • 游戏AI行为决策——GOAP(目标导向型行动规划)

    新的一年即将到来,感觉还剩一种常见的游戏AI决策方法不讲的话,有些过意不去。就在这年的尾巴与大家一起交流下「目标导向型行为规划(GOAP)」吧! 另外,我觉得只是讲代码实现而没有联系具体项目,可能还是不容易理解的。所以这次我会在文末附上一个由本文所述代

    2024年02月04日
    浏览(45)
  • Unity与C++网络游戏开发实战:基于VR、AI与分布式架构 【1.6】

    3.8 Unity中使用协程         协程是在Unity中经常使用的一种辅助处理模式。比如,我们需要设计一个人一边走动一边去观察周围的情况,走动和观察这两种运动同时进行。这时我们可以使用多线程来处理这个问题,但是多线程在内存和CPU的调度时间上具有一些风险。此时在

    2024年04月10日
    浏览(42)
  • 最新开源方案!Cocos Creator 写一个ECS框架+行为树,实现格斗游戏 AI

    引言: 实现游戏 AI 的方式有很多,目前最为常用的主要有有限状态机和行为树。和有限状态机相比,行为树有更好的可扩展性和灵活性,能实现更复杂的 AI 需求。开发者  honmono 在 Cocos Creator 中用一个  ECS + BehaviorTree 框架 实现了一个格斗 AI Demo,一起来看看他的方案。 De

    2024年02月12日
    浏览(48)
  • AGI之Agent:《Generative Agents: Interactive Simulacra of Human Behavior生成代理:人类行为的交互模拟》翻译与解读

    AGI之Agent:《Generative Agents: Interactive Simulacra of Human Behavior生成代理:人类行为的交互模拟》翻译与解读 目录 《Generative Agents: Interactive Simulacra of Human Behavior》翻译与解读 Figure 1: Generative agents are believable simulacra of human behavior for interactive applications. In this work, we demonstrate generat

    2024年01月25日
    浏览(41)
  • 【威胁情报挖掘-论文阅读】学习图表绘制 基于多实例学习的网络行为提取 SeqMask: Behavior Extraction Over Cyber Threat Intelligence

    🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~ 🚀 欢迎一起踏上探险之旅,挖掘无限可能,共同成长! 前些天发现了一个人工智能学习网站,内容深入浅出、易于理解。如果对人工智能感兴趣,不妨点击查看。 论文涉及7位专家的评估,不方便模仿

    2024年03月20日
    浏览(50)
  • Unity行为树可视化编辑器开发

    在ARPG项目的开发过程当中,要涉及到NPC的AI系统,一般来说,简单的AI行为使用状态机即可比较好的实现,但如果NPC的行为稍微一复杂,那么使用状态机来实现就会比较难维护,并且后期工作量会随着NPC状态的增加而成倍增加。 这时就可以考虑使用行为树来实现NPC的AI,行为

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包