Сегодняшний обзор расскажет о том, как я реализовал навигационную сетку, путевые точки и перемещение ИИ.

Я закончил GLI Framework для курса GLI. Цель состояла в том, чтобы закончить некоторые основные механики в игре Sci-Fi Duck Hunt. Мне нужно было реализовать навигационную сетку, ИИ, поведение игрока, HUD, игровой звук, условия победы, условия проигрыша, два бонусных задания, включая взрывную бочку и здоровье барьера.

Цель игры — не дать врагам добраться до верхней двери, чтобы сбежать. Поэтому враги должны путешествовать от начальной точки к конечной. В то же время игрок находится в сторожевой башне, стреляя из винтовки, чтобы остановить их.

Сегодняшний обзор расскажет о том, как я реализовал Navmesh, путевые точки и перемещение ИИ.

Запекание навигационной сетки

Простая задача, я выбрал области, которые я хотел, чтобы ИИ путешествовал. Выделил все объекты на полу и запечь области, чтобы по ним можно было ходить.

Это сгенерировало синий путь для перемещения ИИ из начальной области в конечную. Если вам нужно больше подробностей о том, как запечь путь, вот статья, которую я создал о Navmeshing.

https://medium.com/@jdpetta21/setting-ip-navmesh-in-unity-c6e6621896d3

Настройка ИИ и путевые точки

Время реализовать ИИ; изначально я использовал сферы для представления ИИ, пока не получил от них нужное поведение. У каждого ИИ есть три состояния: бег, скрытие и смерть.

Цель ИИ состояла в том, чтобы появиться в начальной точке и пересечь навигационную сетку до конечной цели. Начальное и конечное местоположения являются пустыми объектами и передаются сценарию ИИ для создания экземпляров и обновления позиции ИИ.

Во время их путешествий путевые точки (розовые точки) будут представлять собой укрытие, и ИИ будет выбирать ближайшую к ним путевую точку, когда они находятся в своей скрыть состояние. Как только они достигли своей конечной цели, их игровой объект был уничтожен, и прозвучал звуковой сигнал, уведомляющий игрока о том, что враг сбежал.

ИИ-скрипт

Это финальная версия модели ИИ, предоставленная Filebase GamedevHQ, а анимации были загружены с Mixmo. На уровне есть восемь путевых точек, представляющих укрытие. Когда объект AI появляется в мире, он собирает все объекты покрытия и добавляет их в список.

    [SerializeField] private List<Transform> _cover;
    [SerializeField] private AudioClip _deathClip;
    private AudioSource AudioSource;
    private Animator _animator;
    private Transform _startingPoint;
    private Transform _endPoint;
    private int _destinationPoint = 0;
    private NavMeshAgent _agent;
    private bool _hiding = false;
    private bool _isDead = false;
    [SerializeField] private AIStates _currentState;

    private void Awake()
    {
        _cover = new List<Transform>();
        _agent = GetComponent<NavMeshAgent>();
        _currentState = AIStates.Run;
        _animator = GetComponent<Animator>();
        AudioSource = GetComponent<AudioSource>();

    }

    void Start()
    {

        _cover = GameObject.Find("Cover").GetComponentsInChildren<Transform>().Skip(1).ToList<Transform>();
        _startingPoint = GameObject.Find("AIStartPoint").transform;
        _endPoint = GameObject.Find("AIEndPoint").transform;
        _agent.destination = _startingPoint.position;
    }

После этого я сохраняю начальную и конечную позиции для ИИ. Затем начинает свое путешествие с agent.destination.

Различные состояния ИИ (метод обновления)

 void Update()
    {
        if (_isDead) _currentState = AIStates.Death;
       
        switch(_currentState)
        {
            case AIStates.Run:
                if (!_hiding)
                {
                    _hiding = true;
                    StartCoroutine(FindCoverRoutine());
                }
                _agent.isStopped = false;
                if (!_agent.pathPending && _agent.remainingDistance < 0.5f) 
                {
                    _agent.destination = _endPoint.position;
                }
                
                break;
           
            case AIStates.Hide:
                if (_agent.remainingDistance < 0.5f) 
                { 
                  _animator.SetBool("Hiding",true);
                    _agent.isStopped = true;
                }
                
                break;

            case AIStates.Death:
                _agent.isStopped = true;
                gameObject.transform.GetComponent<Collider>().enabled = false;
                if (AudioSource.time == 1.5f) AudioSource.Stop();
              _animator.SetBool("Death", true);
                Destroy(this.gameObject, 2f);
                break;

        
        };
    }

В методе обновления у нас есть оператор switch, который управляет поведением ИИ в зависимости от того, в каком состоянии он находится.

  • Состояние выполнения: если ИИ не прячется, продолжайте движение к конечной цели. Если он прячется, запустите сопрограмму, чтобы найти укрытие.
    IEnumerator FindCoverRoutine() 
    {
        yield return new WaitForSeconds(Random.Range(1f, 8f));
        _currentState = AIStates.Hide;
        GetCoverPoint();
        yield return new WaitForSeconds(Random.Range(3f, 5f));
        _hiding = false;
       _animator.SetBool("Hiding", false);
        _currentState = AIStates.Run;
    }
  • Состояние скрытия. ИИ пытается скрыться через случайные промежутки времени. Когда ИИ доберется до укрытия, запустите анимацию сокрытия и замрите на месте. Сопрограмма поиска укрытия приказывает ИИ спрятаться на определенное количество секунд, а затем возвращается в состояние выполнения.

  • Состояние смерти: ИИ перестанет двигаться и отключит свой коллайдер, чтобы игрок не мог непрерывно стрелять для получения дополнительных очков, и будет воспроизводиться анимация смерти со звуком. Как только это будет сделано, игровой объект удалит себя.
    public void Death()
    {
        _isDead = true;
        AudioSource.clip = _deathClip;
        AudioSource.Play();
        StopAllCoroutines();
    }

У меня есть публичный метод смерти, который вызывается, когда ИИ застрелен или убит взрывающейся бочкой — изменение состояния ИИ на смерть.

В заключение, первая часть настройки заключалась в работе над ИИ, запекании навигационной сетки и создании точек укрытия. В следующей статье будут рассмотрены сценарии игрока, такие как стрельба и взаимодействие с окружающей средой.