Unity学习笔记——坦克大战敌人AI

public static bool CanMove = true;
    
    [Header("移动速度")]
    public float moveSpeed = 3f;
    [Header("转身速度")]
    public float turnSpeed = 3f;
    [Header("炮弹的预设体")]
    public GameObject bulletPrefab;
    [Header("炮弹发射的时间间隔")]
    public float fireInterval = 3f;
    [Header("随机旋转的时间间隔")]
    public float randomRotateInterval;
    [Header("炮弹的移动速度")]
    public float bulletMoveSpeed = 3f;
    [Header("炮弹发射点的偏移量")]
    public float firePointOffset = 1.4f;
    
    //玩家
    private Transform player;
    //炮管的Transform
    private Transform tankGun;
    //坦克指向玩家的方向向量
    private Vector3 dir;
    //计时器
    private float timer;
    //射线碰撞检测器
    private RaycastHit hit;
    //发射点
    private Vector3 firePoint;
    //随机的y的角度
    private int y = 0;
    //随机的四元数
    private Quaternion randomQua;
    
    private void Start()
    {
        player = GameObject.FindWithTag("Player").transform;   //通过标签获取玩家
        tankGun = transform.Find("Buttom/Top/Gun");   //查找对应的子对象
    }

    void Update()
    {
        if(!CanMove)   
            return;    //当前不移动直接return 结束
        //计算当前坦克与玩家的距离
        float dis = Vector3.Distance(transform.position, player.position);
        //坦克指向玩家的方向向量
        dir = player.position - transform.position;
        //计算炮弹生成位置
        firePoint = tankGun.position + tankGun.up * firePointOffset;
        
        if (dis < 10)
        {
            Fire();   //如果与玩家的距离小于10调用开火函数
        }
        else if(dis < 20)
        {
            MoveToPlayer();   //大于10小于20向玩家移动
        }
        else
        {
            RandomMove();             //大于20随机移动
        }
    }

    /// <summary>
    /// 转向玩家
    /// </summary>
    private void TurnToPlayer()
    {
        //将方向向量转换为四元数
        Quaternion targetQua = Quaternion.LookRotation(dir);       //自身前方指向目标方向的四元数?
        //Lerp过去   使用差值的方法转向玩家
        transform.rotation = Quaternion.Lerp(transform.rotation,targetQua,Time.deltaTime * turnSpeed);
    }

    /// <summary>
    /// 当前坦克是否已经看向玩家
    /// </summary>
    /// <returns></returns>
    private bool HasLookAtPlayer()
    {
        return Vector3.Angle(dir, transform.forward) < 1;   //当前方向与玩家的夹角小于1度认为已经转向玩家
    }

    /// <summary>
    /// 向玩家开炮
    /// </summary>
    private void Fire()
    {
        //转向玩家
        TurnToPlayer();   
        //判断是否已经瞄准完成
        if (HasLookAtPlayer())
        {
            //计时器计时
            timer += Time.deltaTime;    //计算开火间隔
            if (timer > fireInterval)
            {
                //从炮口位置向玩家发射物理射线
                if (Physics.Raycast(firePoint, dir,out hit,10))
                {
                    //查看碰撞体的根对象是否是玩家
                    if (hit.transform.root.tag == "Player")
                    {
                        //生成炮弹
                        GameObject crtBullet = Instantiate(bulletPrefab, firePoint, Quaternion.identity);
                        //给炮弹一个速度让沿某个方向进行移动
                        crtBullet.GetComponent<Rigidbody>().velocity = transform.forward * bulletMoveSpeed;
                        //定时自动销毁
                        Destroy(crtBullet,3f);
                    }
                }
                //计时器归零
                timer = 0;
            }
        }
    }

    private void MoveToPlayer()
    {
        //转向玩家
        TurnToPlayer();
        //检测炮管前方两米的正方形范围内是否有友军
        if (Physics.CheckBox(firePoint + transform.forward,new Vector3(1, 1, 1),
            Quaternion.identity, ~(1 << 9)))    //最后参数表示忽略某一层
        {
            //直接返回
            return;
        }

        //向前移动
        transform.position += transform.forward * Time.deltaTime * moveSpeed;
    }

    private void RandomMove()
    {
        timer += Time.deltaTime;
        
        if (timer > randomRotateInterval)       //每隔一段时间随机一个旋转角度
        {
            y = Random.Range(0, 360);
            randomQua = Quaternion.Euler(Vector3.up * y);    //自身沿某个轴旋转一定度数的四元数?
            timer = 0;
        }
        //lerp过去
        transform.rotation = Quaternion.Lerp(transform.rotation,
            randomQua,Time.deltaTime * turnSpeed);

        if (Physics.Raycast(firePoint, transform.forward, out hit, 3))     //如果前方3米处有坦克重新随机一个方向
        {
            y = Random.Range(0, 360);
            randomQua = Quaternion.Euler(Vector3.up * y);
            return;
        }

        transform.position += transform.forward * Time.deltaTime * moveSpeed;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值