使用Behavior Designer插件简单制作NPC AI

来源:互联网 发布:javascript eval 编辑:程序博客网 时间:2024/05/14 22:45

简单用Behavior Designer插件实现:当敌人发现玩家后开始追踪玩家,当追上玩家时发动攻击



Behavior Designer自带了一些Task,但是要实现自己的需求,必须动手写自己的Task。

这个Demo用到三个自定义Task:

1. WithinSight (用于判断攻击目标是否在视线内)

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;[TaskCategory("Custom")]//此Task将显示在Custom栏目下[TaskDescription("判断目标是否在视野中")]public class WithinSight : Conditional//继承Behavior Designer的Conditional类,将会显示在BehaviorDesigner Task面板中的Conditional栏目下{    public string targetTag;//目标的Tag    public float viewLength;//视野范围    public SharedTransform target;//SharedTransform是BehaviorDesigner的类型,对应Transform类型。顾名思义,就是将此变量共享,以便其它Task访问,需要在Variables面板中定义出一个同类型变量以接收此变量    private Transform[] possibleTargets;//所有targetTag的目标    public override void OnAwake()    {        var targets = GameObject.FindGameObjectsWithTag(targetTag);        possibleTargets = new Transform[targets.Length];        for (int i = 0; i < targets.Length; i++)        {            possibleTargets[i] = targets[i].transform;        }    }    public override TaskStatus OnUpdate()    {        for (int i = 0; i < possibleTargets.Length; i++)        {            if (withinSight(possibleTargets[i], viewLength))            {                target.Value = possibleTargets[i];                return TaskStatus.Success;//如果找到目标返回Task成功            }        }        return TaskStatus.Failure;//如果没找到目标返回Task失败    }    public bool withinSight(Transform targetTransform, float viewLength)    {        RaycastHit rayCast;        Vector3 direction = targetTransform.position - transform.position;        var hit = Physics.Raycast(transform.position, direction, out rayCast, viewLength);                if(hit && rayCast.collider.tag == "Player")        {            return true;        }        else        {            return false;        }    }}

2. MoveToward(用于追赶目标)

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;[TaskCategory("Custom")][TaskDescription("移动")]public class MoveToward : Action {    public float speed = 0;    //[RequiredField]    public SharedTransform target;    public override TaskStatus OnUpdate()    {        if((transform.position.x-target.Value.position.x)<0.1f)        {            return TaskStatus.Success;        }        transform.position += transform.forward * (speed * Time.deltaTime);        return TaskStatus.Running;    }}

3. Attack (攻击)

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;[TaskCategory("Custom")][TaskDescription("攻击")]public class Attack : Action {    private bool isAttack;    private GameObject weapon;    private float fireRate = 1.0f;    public override void OnAwake()    {        weapon = transform.FindChild("RayLine").gameObject;    }    public override void OnStart()    {            }    public override TaskStatus OnUpdate()    {        fireRate -= Time.deltaTime;        if(fireRate < 0)        {            Fire();            fireRate = 1.0f;            return TaskStatus.Running;        }        else        {            if (weapon.activeSelf)                weapon.SetActive(false);        }        return TaskStatus.Failure;    }    private void Fire()    {        weapon.SetActive(true);    }}

4. 创建Repeater节点,勾选Repeat Forever让敌人实时判断



5.创建Sequence节点,此节点下的分支将从左到右逐个执行,遇到Task返回失败则不再往下执行


6. 在Sequence节点下创建三个自定义节点作为其子节点,对变量进行赋值。这里的Target变量需要共享给MoveToward节点用,所以要在Variable中定义一个Transform类型变量target,赋值给Target



0 0