untiy 3d结合Brainiac Designer做游戏Ai(二)

来源:互联网 发布:linux断点续传命令py 编辑:程序博客网 时间:2024/05/20 05:09

上一篇已经介绍了怎么用Brainiac Designer做行为树,这一篇将会介绍怎么把生成的ai结合到untiy里

首先导出的ai代码拷到untiy里,然后新建一个行为树框加BehaviorTree.cs,定义各种节点,代码比较简单,根本的注释也有了,就不详细讲了,代码如下

using UnityEngine;using System.Collections;using System.Collections.Generic;namespace GameAi{    public interface IBehaviorTreeNode    {        bool Process(AiController theOwner);    }    /// <summary>    /// 行为框架,具体实现要继承DecoratorNode, ConditionNode, ActionNode, ImpulseNode    /// </summary>    public class BehaviorTreeRoot : IBehaviorTreeNode    {        public IBehaviorTreeNode root = null;        public BehaviorTreeRoot()        {        }        public bool Process(AiController theOwner)        {            return root.Process(theOwner);        }        public void AddChild(IBehaviorTreeNode root)        {            this.root = root;        }    }    /// <summary>    /// 复合节点,不能为叶子节点    /// </summary>    public class CompositeNode : IBehaviorTreeNode    {        protected List<IBehaviorTreeNode> children = new List<IBehaviorTreeNode>();        /// <summary>        /// 由子树实现        /// </summary>        /// <param name="theOwner"></param>        /// <returns></returns>        public virtual bool Process(AiController theOwner)        {            return true;        }        public void AddChild(IBehaviorTreeNode _node)        {            children.Add(_node);        }        public void DelChild(IBehaviorTreeNode _node)        {            children.Remove(_node);        }        public void ClearChildren()        {            children.Clear();        }    }    /// <summary>    /// 修饰类    /// </summary>    public class DecoratorNode : IBehaviorTreeNode    {        protected IBehaviorTreeNode child = null;        /// <summary>        /// 由子类实现        /// </summary>        /// <param name="theOwner"></param>        /// <returns></returns>        public virtual bool Process(AiController theOwner)        {            return child.Process(theOwner);        }        public void Proxy(IBehaviorTreeNode _child)        {            child = _child;        }    }    /// <summary>    /// 脉冲类    /// </summary>    public class ImpulseNode : IBehaviorTreeNode    {        protected IBehaviorTreeNode child = null;        /// <summary>        /// 由子类实现        /// </summary>        /// <param name="theOwner"></param>        /// <returns></returns>        public virtual bool Process(AiController theOwner)        {            return child.Process(theOwner);        }        public void Proxy(IBehaviorTreeNode _child)        {            child = _child;        }    }    /// <summary>    /// 叶子节点,条件判断类    /// </summary>    public class ConditionNode : IBehaviorTreeNode    {        /// <summary>        /// 由子类实现        /// </summary>        /// <param name="theOwner"></param>        /// <returns></returns>        public virtual bool Process(AiController theOwner)        {            return false;        }    }    /// <summary>    /// 叶子节点,具体行为实现类    /// </summary>    public class ActionNode : IBehaviorTreeNode    {        /// <summary>        /// 由子类实现        /// </summary>        /// <param name="theOwner"></param>        /// <returns></returns>        public virtual bool Process(AiController theOwner)        {            return false;        }    }    /// <summary>    /// 选择节点    /// 遇到一个child执行后返回true,停止迭代    /// 本node向自己的父节点返回true    /// 如果所有的child都返回false,本node向自己父节点返回false    /// </summary>    public class SelectorLinear : CompositeNode    {        public override bool Process(AiController theOwner)        {            foreach (IBehaviorTreeNode _node in children)            {                if (_node.Process(theOwner))                {                    return true;                }            }            return false;        }    }    /// <summary>    /// 遇到一个child执行后返回false,停止迭代    /// 本node向自己的父节点返回false    /// 如果所有的child都返回true,本node向自己父节点返回true    /// </summary>    public class SequenceLinear : CompositeNode    {        public override bool Process(AiController theOwner)        {            foreach (IBehaviorTreeNode _node in children)            {                if (!_node.Process(theOwner))                {                    return false;                }            }            return true;        }    }    /// <summary>    /// 修饰类取反    /// </summary>    public class DecoratorNot : DecoratorNode    {        public override bool Process(AiController theOwner)        {            return !base.Process(theOwner);        }    }}
打开Brainiac Designer导出的代码可以看到,里面只是添加一些节点,但是节点要干什么,里面没有实现了,所以我们要在untiy里实现各个节点的行为

首先是Attack.cs

using UnityEngine;using System.Collections;namespace GameAi{    public class Attack : ActionNode    {        public Attack()        {        }        public override bool Process(AiController theOwner)        {            theOwner.Attack();            return true;        }    }}

CanNotFindPlayer.cs

using UnityEngine;using System.Collections;namespace GameAi{    public class CanNotFindPlayer : ConditionNode    {        public CanNotFindPlayer()        {        }        public override bool Process(AiController theOwner)        {            return theOwner.CanNotFindPlayer();        }    }}

Chase.cs


using UnityEngine;using System.Collections;namespace GameAi{    public class Chase : ActionNode    {        public Chase()        {        }        public override bool Process(AiController theOwner)        {            theOwner.Chase();            return true;        }    }}

FindPlayer.cs

using UnityEngine;using System.Collections;namespace GameAi{    public class FindPlayer : ConditionNode    {        public FindPlayer()        {        }        public override bool Process(AiController theOwner)        {            return theOwner.FindPlayer();        }    }}

IsPlayerInAttackRange.cs

using UnityEngine;using System.Collections;namespace GameAi{    public class IsPlayerInAttackRange : ConditionNode    {        public IsPlayerInAttackRange()        {        }        public override bool Process(AiController theOwner)        {            return theOwner.IsPlayerInAttackRange();        }    }}


Patrol.cs

using UnityEngine;using System.Collections;namespace GameAi{    public class Patrol : ActionNode    {        public int PatrolRange = 0;        public Patrol()        {        }        public override bool Process(AiController theOwner)        {            theOwner.Patrol(PatrolRange);            return true;        }    }}

行为树的各个节点已经定义好, 我们还需要定义一个Ai控制器AiController,Ai的的具体逻辑都是写在这里,根据名称用反射去决定调用哪个ai行为树,行为树的节点的具体行为只是调用这里的方法

AiController.cs

using UnityEngine;using System.Collections;using GameAi.Manager;namespace GameAi{    public class AiController : MonoBehaviour    {        private BehaviorTreeRoot _aiBehaviorTree;        private string _aiBTreeName = "ai_1";        private float _aiIntervalTick = 0f;        private float _aiIntervalTime = 0.5f;        private void RegisterAiBehaviorTree()        {            _aiBehaviorTree = BTreeManager.instance.GetBTree(_aiBTreeName);        }        // Use this for initialization        void Start()        {            RegisterAiBehaviorTree();        }        void FixedUpdate()        {            //ai执行时间间隔处理            if (_aiIntervalTick == -1f)            {                _aiBehaviorTree.Process(this);                _aiIntervalTick = 0f;            }            else            {                _aiIntervalTick += Time.deltaTime;                if (_aiIntervalTick >= _aiIntervalTime)                {                    _aiBehaviorTree.Process(this);                    _aiIntervalTick = 0f;                }            }        }        public void Chase()        {            Debug.Log("==========Chase======= ");        }        public void Attack()        {            Debug.Log("=========Attack========");        }        public void Patrol(int patrolRange)        {            Debug.Log("=========Patrol========" + patrolRange);        }        public bool FindPlayer()        {            Debug.Log("=========FindPlayer========");            if (Random.Range(0, 10) > 5)            {                return false;            }            return true;        }        public bool IsPlayerInAttackRange()        {            Debug.Log("=========IsPlayerInAttackRange========");            if (Random.Range(0, 10) > 5)            {                return false;            }            return true;        }        public bool CanNotFindPlayer()        {            Debug.Log("=========CanNotFindPlayer========");            if (Random.Range(0, 10) > 5)            {                return false;            }            return true;        }    }}

整个Ai框架到这里已经定义好了,最后把AiController拖到一个GameObject上,执行就可以看到运行结果了

最后附上整个工程文件:源码

简单的Ai也可以用FSM实现,这里不细讲附上一个用FSM实现的Ai工程:源码


0 0
原创粉丝点击