毕业设计的坑--unity ai的设计,我选择使用behavior tree插件(5)

来源:互联网 发布:matlab中做数据预测 编辑:程序博客网 时间:2024/06/08 07:39

============策划部分==================

Ai在我的设计中是全场中立怪物。

当怪物血量100%的时候----->怪物到处游走,自由闲灌。

当怪物血量<100% && 怪物血量>30% 的时候------->怪物处于普通状态,在player范围内进行追踪攻击。

当怪物血量 <30%的时候---------->怪物处于激怒状态,攻速和移动速度和外形都发生了变化,一直追着玩家进行攻击。

===================behavior的设计上======================

根据上面的策划方案于是就出了这个behavior tree了。对于读者还没用过behavior tree插件,我决定给大家先简单的说下,behavior tree的插件用法。



======================详细讲述下behavior tree插件的用法============================

里面分为有4大组件:

组件一、composites

里面有两个最重要的两个,

selector :选择执行,当子节点返回成功的时候才会停止执行这棵树

sequence:顺序执行,当子节点返回失败的时候才会停止执行这棵树

其中里面有个选项值的去注意下的,打断的类型,里面有4个选项。

self:允许打断自身自己的子树的执行

lower Priority:可以打断比自己优先级别低的树

both:self+lower Priority

none:没有


组件二、decorators

这个组件是装饰组件,我也没怎么用过。

组件二、actions

antion动作一返回runing将一直执行。

这里可以参考下我自己写的几个Action

怪物被激怒后触发的action

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;public class ActionMonitorChange : Action {    public EmemyObject ememy;    public override void OnStart()    {        base.OnStart();        ememy = this.GetComponent<EmemyObject>();    }    public override TaskStatus OnUpdate()    {        //return base.OnUpdate();        ememy.MonitorChange();        return TaskStatus.Success;    }}
追踪target直到到达指定距离(这个脚本要加上用到unity自带的navgation的导航)

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;public class MySeek : Action{    public SharedTransform target;//要到达的target位置    public float speed;//移动的speed    public float distanceMax;//相隔的的距离    private float distanceMaxSquare;//距离的平方    public override void OnStart()    {        base.OnStart();        distanceMaxSquare = distanceMax * distanceMax;    }    public override TaskStatus OnUpdate()    {        //base.OnUpdate();        this.transform.position =  Vector3.MoveTowards(this.transform.position,target.Value.position,Time.deltaTime*speed);        this.transform.LookAt(target.Value);        float distance = (target.Value.position - this.transform.position).sqrMagnitude;//x*x+y*y+z*z计算距离        if(distance <= distanceMaxSquare){            return TaskStatus.Success;        }        return TaskStatus.Running;    }}

组件四、conditionals

判定条件,返回成功和失败

可以参考下我写的

在距离和范围内返回成功找到敌人,否则返回失败

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;public class MyCanSeeObject1_0 : Conditional {    public SharedGameObject target;//要监视的transform的数组    public float distance;//距离的最远距离    private float distanceSquare;//距离的平方    public float canSeeAngle;//能看见的角度    private float canSeeAngleAvg;//为节省效率实现而计算的canSeeAngle/2    public SharedTransform returnTarget;    public SharedGameObject retureGameObject;//返回的GameObject        public override void OnStart()    {        base.OnStart();        distanceSquare = distance * distance;        canSeeAngleAvg = canSeeAngle / 2;    }    public override TaskStatus OnUpdate()    {                //foreach(Transform target in targets){            float curAngle = Vector3.Angle(this.transform.forward ,target.Value.transform.position-this.transform.position);//object当前的正前方向量与,要监视的物体的角度            if (curAngle <= canSeeAngleAvg)            {                //在角度范围内                //判断是否在距离范围内                float distance = (target.Value.transform.position - this.transform.position).sqrMagnitude;                //Debug.Log("distance:"+ distance);                if (distance<= distanceSquare)                {                    //在距离范围内                                        this.returnTarget.Value = target.Value.transform;                    this.retureGameObject.Value = target.Value.gameObject;                    return TaskStatus.Success;                }            }        //}        return TaskStatus.Failure;            }}

血量判断

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;//behavior tree上的血量是100的时候public class IsHealth100 : Conditional{    public EmemyObject wolf;    public override void OnStart()    {        base.OnStart();        wolf = this.GetComponent<EmemyObject>();    }    public override TaskStatus OnUpdate()    {        if (wolf.blood == wolf.bloodMax)        {            return TaskStatus.Success;        }        return TaskStatus.Failure;//失败的返回    }}

血量在范围内判断

using UnityEngine;using System.Collections;using BehaviorDesigner.Runtime;using BehaviorDesigner.Runtime.Tasks;//监视怪物在血量between之间的时候public class IsHealthBetween : Conditional{    public EmemyObject wolf;    public int lowNum = 4;//最小值    public int upNum = 12;//最大值    public override void OnStart()    {        base.OnStart();        wolf = this.GetComponent<EmemyObject>();    }    public override TaskStatus OnUpdate()    {                if (wolf.blood >= lowNum && wolf.blood <= upNum)        {            return TaskStatus.Success;        }        return TaskStatus.Failure;    }}

=====================至此,一个完整的随心所欲的ai算是完成了=============


0 0
原创粉丝点击