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

上一篇已经介绍了怎么用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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值