Сегодняшний обзор расскажет о том, как я реализовал навигационную сетку, путевые точки и перемещение ИИ.
Я закончил 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(); }
У меня есть публичный метод смерти, который вызывается, когда ИИ застрелен или убит взрывающейся бочкой — изменение состояния ИИ на смерть.
В заключение, первая часть настройки заключалась в работе над ИИ, запекании навигационной сетки и создании точек укрытия. В следующей статье будут рассмотрены сценарии игрока, такие как стрельба и взаимодействие с окружающей средой.