手动写一个Behavior Designer任务节点

转自:  http://blog.csdn.net/qq_33747722/article/details/53539532

转自:  https://my.oschina.net/acitiviti/blog/625799


在Behavior Designer的可视化节点实际都是由脚本语言编写出来的

自己手写一个类似于CanSeeObject、Seek等任务节点并不是一件难事.

下面我介绍CanSeeObject和Seek任务节点的代码生成,基本成功实现了原来节点的功能

LJLCanSeeObject代码如下:

using UnityEngine;  
using System.Collections;  
using BehaviorDesigner.Runtime;  
using BehaviorDesigner.Runtime.Tasks;  
 
#region 检测选中的游戏对象是否在视野内  
  
/// <summary>  
///CanSeeObject是在Conditional下的节点,因此自己手动写的一个类似于CanSeeObject的节点继承自Conditional,在这里命名为LJLCanSeeObject  
/// </summary>  
public class LJLCanSeeObject : Conditional  
{  
    /// <summary>  
    /// 视野内检测的目标对象  
    /// </summary>  
    public Transform[] targets;  
    /// <summary>  
    /// 视野角度  
    /// </summary>  
    public float fieldOfViewAngle = 90;  
    /// <summary>  
    /// 视野距离(共享变量)  
    /// </summary>  
    public SharedFloat sharedViewDistance;  
    /// <summary>  
    /// 在视野内检测到的游戏对象位置(共享变量,在这里将检测到的游戏对象位置数据附给它)  
    /// </summary>  
    public SharedTransform target;  
  
    public override TaskStatus OnUpdate()  
    {  
        if (targets == null) return TaskStatus.Failure;  
        foreach (var target in targets)  
        {  
            float distance = (target.position - transform.position).magnitude;  
            float angle = Vector3.Angle(transform.forward, target.position - transform.position);  
            if (distance < sharedViewDistance.Value && angle < fieldOfViewAngle * 0.5f)  
            {  
                //将检测到的游戏对象位置数据附给共享变量  
                this.target.Value = target;  
                return TaskStatus.Success;  
            }  
        }  
        return TaskStatus.Failure;  
    }  
}  
 
#endregion  

LJLSeek代码如下:

using UnityEngine;  
using System.Collections;  
using BehaviorDesigner.Runtime;  
using BehaviorDesigner.Runtime.Tasks;  
 
#region 控制游戏物体到达目标位置  
  
public class MySeek : Action   
{  
    /// <summary>  
    /// 行走速度(共享变量)  
    /// </summary>  
    public SharedFloat sharedSpeed;  
    /// <summary>  
    /// 目标位置(共享变量)  
    /// </summary>  
    public SharedTransform target;  
    /// <summary>  
    /// 到达目的地的距离(共享变量)  
    /// </summary>  
    public SharedFloat sharedArriveDistance = 0.1f;  
    private float sqrArriveDistance;  
  
    public override void OnStart()   
    {  
        sqrArriveDistance = sharedArriveDistance.Value*sharedArriveDistance.Value;  
    }  
  
  
    //当进入到这个任务的时候,会一直调用这个方法,直到任务结束   
    //返回一个 Success 或者 Failure 的状态,那么任务结束   
    //返回一个Running的状态,则这个方法会继续调用  
    public override TaskStatus OnUpdate()   
    {  
        if (target == null||target.Value==null)   
        {  
            return TaskStatus.Failure;  
        }  
  
        transform.LookAt(target.Value.position);//直接朝向目标位置  
        transform.position= Vector3.MoveTowards(transform.position, target.Value.position, sharedSpeed.Value*Time.deltaTime);  
  
        if ((target.Value.position - transform.position).sqrMagnitude < sqrArriveDistance)   
        {  
            //当距离目标位置的距离比较小时,认为到达了目标位置,直接return成功  
            return TaskStatus.Success;  
        }  
  
        return TaskStatus.Running;  
    }  
}  
#endregion  

接下来Conditionals条件节点有个LJLCanSeeObject节点可以选择使用。

Actions行为节点有个LJLSeek节点可以选择使用。

行为树是一组任务的集合。任务拥有和unity MonoBehaviour 相似的API,所以他很容易的让你创建一个任务(创建任务将在后面章节详细讲解)。任务类有如下API:
// OnAwake is called once when the behavior tree is enabled. Think of it as a constructor
public virtual void OnAwake();

// OnStart is called immediately before execution. It is used to setup any variables that need to be reset from the previous run
public virtual void OnStart();

// OnUpdate runs the actual task
public virtual TaskStatus OnUpdate();

// OnEnd is called after execution on a success or failure. 
public virtual void OnEnd();

// OnPause is called when the behavior is paused and resumed
public virtual void OnPause(bool paused);

// The priority select will need to know this tasks priority of running
public virtual float GetPriority();

// OnBehaviorComplete is called after the behavior tree finishes executing
public virtual void OnBehaviorComplete();

// OnReset is called by the inspector to reset the public properties
public virtual void OnReset();

// Allow OnDrawGizmos to be called from the tasks
public virtual void OnDrawGizmos();

// Keep a reference to the behavior that owns this task
public Behavior Owner;

 任务有三个共有的属性:名称,注释,瞬时状态。瞬时状态是三个属性中一个不太容易理解的属性。在一个相同的循环周期中,一个任务返回成功或者失败后,任务将立刻运行下一个任务,先前的任务将处于等待状态。这种模式有利于减少行为树性能消耗。

     下图显示了任务运行的流程:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值