【Unity3d】游戏智能

坦克对战游戏 AI 设计

从商店下载游戏:“Kawaii” Tank 或 其他坦克模型,构建 AI 对战坦克。具体要求:

  • 使用“感知-思考-行为”模型,建模 AI 坦克
  • 场景中要放置一些障碍阻挡对手视线
  • 坦克需要放置一个矩阵包围盒触发器,以保证 AI 坦克能使用射线探测对手方位
  • AI 坦克必须在有目标条件下使用导航,并能绕过障碍。(失去目标时策略自己思考)
  • 实现人机对战

效果截图


具体实现

本次作业难度较大,根据已有的代码进行修改。
参考博客:坦克对战游戏 AI 设计

重要代码如下:

TankAI

TankAI类作为“感知-思考-行为”模型中的“思考”。跟踪速度和角速度随距离发生变化,距离越近速度越慢角速度越快。射线检测玩家在正前方时发射子弹,使用射线使AI坦克不会频繁发射子弹,行为更自然。

using System;
using UnityEngine;
namespace Complete
{
    [RequireComponent(typeof (UnityEngine.AI.NavMeshAgent))]
    public class TankAI : MonoBehaviour
    {
        public UnityEngine.AI.NavMeshAgent agent { get; private set; }
        public Transform target;
        public float angle = 60f;

        private float countTime = 0;
        private void Start()
        {
            agent = GetComponentInChildren();
            agent.updateRotation = true;
            agent.updatePosition = true;
        }

        private void Update()
        {
            // 距离与40的比例
            float ratio = (target.transform.position - transform.position).magnitude / 40;
            // 导航速度与距离线性正相关
            agent.speed = 2f * ratio + 1.5f;
            // 导航角速度与距离线性负相关
            agent.angularSpeed = 120f - 60f * ratio;
            if (target != null)
                agent.SetDestination(target.position);
            // 玩家在正前方时,以0.2秒一次的频率发射子弹
            if (countTime >= 0.2f) {
                Ray ray = new Ray (transform.position, transform.forward);
                RaycastHit hit;  
                if (Physics.Raycast (ray, out hit, Mathf.Infinity)) { 
                    if (hit.collider.gameObject.tag == "Player")
                        GetComponent ().MyShoot();
                }
                countTime = 0;
            }
            countTime += Time.deltaTime;
        }
    }
}

TankManager

如果对象是AI,不激活TankMovement组件,使AI坦克不能被用户控制。

public void EnableControl ()
{
    if (!AI)
        m_Movement.enabled = true;
    else
        m_Instance.GetComponent ().enabled = true;
    ...
}

GameManager

设置Player2坦克的TankManager的AI为true,TankAI的导航目标target为Player1的位置。

private void SpawnAllTanks()
{
    ...
    m_Tanks [0].AI = false;
    m_Tanks [1].AI = true;
    m_Tanks [1].m_Instance.GetComponent<TankAI> ().target = m_Tanks [0].m_Instance.transform;
    m_Tanks [1].m_Instance.GetComponent<TankAI> ().enabled = false;
}

你可能感兴趣的:(Unity3D)