unity3d AI 学习--个体行为操控(1)--具体行为类(3)-路径跟随和躲避障碍


摘自《Unity3D人工智能编程精粹》


同样是继承Steering。

首先是路径跟随的脚本:

using UnityEngine;
using System.Collections;

public class SteeringFollowPath : Steering {
    //路径
    public GameObject[] wayPoints ;
    //目标点
    private Transform target;
    //当前路点
    private int currentNode;
    //当与路点小于这个距离的时候,就认为已经到达了,就可以去下一个了
    private float arriveDistance;
    private float sqrArriveDistance;
    //路径长度
    private int numberOfNode;

    private Vector3 force;

    private Vector3 desiredVelocity;

    private Vehicle _vehicle;

    private float maxSpeed;

    private bool isPlanar;
    //开始减速的距离
    public float slowDownDistance;

    void Start()
    {
        numberOfNode = wayPoints.Length;

        _vehicle = GetComponent<Vehicle>();
        maxSpeed = _vehicle.maxSpeed;
        isPlanar = _vehicle.isPlanar;

        currentNode = 0;
        //设置当前路点
        target = wayPoints[currentNode].transform;

        arriveDistance = 1.0f;

        sqrArriveDistance = arriveDistance * arriveDistance;
    }

    public override Vector3 Force()
    {
        force = Vector3.zero;

        Vector3 dist = target.position - transform.position;

        if(isPlanar )
        {
            dist.y = 0;
        }
        //最后一个路点
        if (currentNode == numberOfNode - 1)
        {
            //按正常速度前进
            if (dist.magnitude > slowDownDistance)
            {
                desiredVelocity = dist.normalized * maxSpeed;

                force = desiredVelocity - _vehicle.velocity;
            }
            else
            {
                //开始减速前进
                desiredVelocity = dist - _vehicle.velocity;
                force = desiredVelocity - _vehicle.velocity;
            }
        }
        else
        {
            //走向下一个路点
            if(dist.sqrMagnitude <sqrArriveDistance )
            {
                currentNode++;
                target = wayPoints[currentNode].transform;
            }
            desiredVelocity = dist.normalized * maxSpeed;
            force = desiredVelocity - _vehicle.velocity;
        }

        return force;
    }
}

然后是躲避障碍物的脚本:、


using UnityEngine;
using System.Collections;

public class SteeringCollisionAvoidance : Steering  {
    public bool isPlanar;

    private Vector3 desiredVelocity;

    private Vehicle _vehicle;

    private float maxSpeed;

    private float maxForce;
    //躲避障碍的力
    public float avoidanceForce;
    //所能看到的最大距离的障碍物
    public float maxSeeAhead = 2.0f;
    //场景中所以障碍物的数组
    private GameObject[] allColliders;

    void Start()
    {
        _vehicle = GetComponent<Vehicle>();

        maxSpeed = _vehicle.maxSpeed;
        maxForce = _vehicle.maxForce;
        isPlanar = _vehicle.isPlanar;

        if(avoidanceForce >maxForce )
        {
            avoidanceForce = maxForce;
        }

        allColliders = GameObject.FindGameObjectsWithTag("obstacle");
    }

    public override Vector3 Force()
    {
        RaycastHit hit;

        Vector3 force = Vector3.zero;
        Vector3 velocity = _vehicle.velocity;
        Vector3 normalizedVelocity = velocity.normalized;
        //画出射线检测障碍物
        Debug.DrawLine(transform.position, transform.position 
            + normalizedVelocity * maxSeeAhead
            * (velocity.magnitude / maxSpeed));

        if(Physics .Raycast (transform .position ,normalizedVelocity ,
            out hit ,
            maxSpeed *velocity .magnitude /maxSpeed ))
        {
            //如果射线与某个物体相交,表示有可能与该物体发生碰撞了
            Vector3 ahead = transform.position + normalizedVelocity * maxSeeAhead
                * (velocity.magnitude / maxSpeed);
            //计算躲避所需要的力
            force = ahead - hit.collider.transform.position;

            force *= avoidanceForce;

            if(isPlanar )
            {
                force.y = 0;
            }
            //更改碰撞体的颜色
            foreach (GameObject  c in allColliders )
            {
                if(hit .collider .gameObject ==c)
                {
                    c.GetComponent<Renderer>().material.color = Color.red;
                }
                else
                {
                    c.GetComponent<Renderer>().material.color = Color.white;
                }
            }
        }
        else
        {
            //将其余不能发生碰撞的物体设置为白色
            foreach (GameObject  c in allColliders )
            {
                c.GetComponent<Renderer>().material.color = Color.white;
            }
        }
        return force;
    }
}

为了方便观察,还有下面的这个脚本:

using UnityEngine;
using System.Collections;

public class CollisionColorChange : MonoBehaviour {
    void OnTriggerEnter(Collider other)
    {
        if(other .gameObject .GetComponent <Vehicle >()!=null )
        {
            this.GetComponent<Renderer>().material.color = Color.red;
        }
    }

    void OnTriggerExit(Collider other)
    {
        this.GetComponent<Renderer>().material.color = Color.gray;
    }
}

原谅我作为原创发表,这本书的确很好,比我之前看到的一个外国大神写的《unity3d人工智能编程》更加详细和全面,我会每天发表一篇博客,作为学习记录的.......

人笨,跟着各路大神学习有汤喝就足够了


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值