Создание AI в 2D игре
| |
Knife_Kill | Дата: Вторник, 28 Июля 2015, 19:58 | Сообщение # 1 |
частый гость
Сейчас нет на сайте
| Здравствуйте! Как реализовать передвижение противника (да и вообще, любого предмета) в Юньке? (Я имею ввиду простые AI) Многие, наверно, скажут - NavMesh в помощь тебе, но не тут-то было, он работает только с MeshRender'om. Так же я наткнулся на NavMesh2D (который в Assetах стоит 15$), естественно скачал, все сделал как в уроке, вроде заработало, но только при нажатии на "E". Стоит мне убрать строчку с "if(Input...)" как вдруг ничего не работает (причем я очень многое пытался пихать вместо этого If'a, все без толку). Код using PigeonCoopToolkit.Navmesh2D; using UnityEngine; using System.Collections; using System.Collections.Generic;
public class PathFollower : MonoBehaviour {
public Transform pathingTarget; private List<Vector2> path; // LateUpdate is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.E)) { path = NavMesh2D.GetSmoothedPath(transform.position, pathingTarget.position); }
if(path != null && path.Count != 0) { transform.position = Vector2.MoveTowards(transform.position, path[0], 5*Time.deltaTime); if(Vector2.Distance(transform.position,path[0]) < 0.01f) { path.RemoveAt(0); } } } }
Прокопавшись долгое время с этим скриптом, нашел другой урок, с таким вот коддом (примерно): Код using UnityEngine; using System.Collections;
public class AI : MonoBehaviour {
public GameObject Cube_1; public GameObject Cube_2;
// Use this for initialization void Start () { } // Update is called once per frame void Update () {
if(Vector3.Distance(transform.position, Cube_1.transform.position) <= 1f) { // transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Cube_2.transform.position - transform.position), 270 * Time.deltaTime); transform.rotation = new Quaternion(0, -180, 0, 0); transform.position += Vector3.forward * 50 * Time.deltaTime; }
if (Vector3.Distance(transform.position, Cube_2.transform.position) <= 1f) { transform.rotation = new Quaternion(0, -180, 0, 0); transform.position += Vector3.forward * 50 * Time.deltaTime; }
} } И код тоже, вроде бы, работает. Но объект на котором висит этот скрипт не двигается, куда бы я transform.position... не ставил. У меня возникло несколько вопросом, каким лучше путем двигаться? Через скаченный NavMesh или же через этот полу-самописный код? И, наконец, почему не работает transform.position (во втором коде) или же не срабатывает "path = NavMesh2D.GetSmoothedPath(transform.position, pathingTarget.position);" если я уберу или изменю if(...)? Или же мне лучше не заморачиваться с этим и поискать еще способы?
|
|
| |
KamiRonin | Дата: Вторник, 28 Июля 2015, 21:30 | Сообщение # 2 |
почти ветеран
Сейчас нет на сайте
| в случае с NavMesh2D у тебя скорее всего возникает постоянное перестраивание пути, когда ты убираешь строчку с Input. совет: сделай локальную переменную bool pathEnter - и в Update проверяй - если она ложная, то: 1 - строй путь до таргета, 2 - устанавливай pathEnter в истину. В этом случае придется добавить еще одну проверку - точка предыдущего (при построении пути) таргета достигнута? Если да - то pathEnter = false; (это вызовет построение пути заново на следующем цикле Update).
в случае с трансформом у тебя там проверка по vector3, иногда по недосмотру - третья координаты цели и юнита слишком далеко, поэтому условия проверки на дистанцию не срабатывают. совет: 1 - переведи в Vector2 все проверки - у него тоже есть дистанс; 2 - поиграйся с числом, на которое проверяется дистанция - вместо 1, возьми 10 и тп..
тут есть версия как выкрутиться без навМеш2Д (урок на английском). может пригодится..
Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Сообщение отредактировал KamiRonin - Вторник, 28 Июля 2015, 21:31 |
|
| |
Knife_Kill | Дата: Среда, 29 Июля 2015, 12:50 | Сообщение # 3 |
частый гость
Сейчас нет на сайте
| KamiRonin, Спасибо, попробую разобраться. Начну, тогда, с трансформа...Добавлено (29 июля 2015, 12:50) --------------------------------------------- В общем, с горем-пополам решил проблему с Navmesh'em, но появилась другая. (Код, тупо скопированный отсюда (позже перепишу сам). Проблема заключается в том, что противник следит за нами, но он вертится по оси y "на сколько хочет", как сделать поворот строго на 180 градусов? На сколько я понимаю, как- то в LookAt это можно сделать, но как? Код public class Enemy : MonoBehaviour { public Transform _target; // Указываем переменную, к которой будет двигаться наш агент NavMeshAgent _agent; // Указываем переменную агента Transform _home;
void Start() { _agent = (NavMeshAgent)this.GetComponent("NavMeshAgent"); // Указываем, что переменная _agent - это наш агент. }
void Update() { GameObject player = GameObject.FindGameObjectWithTag("Player"); pos.y = transform.position.y; _home = transform.parent.transform; _agent.SetDestination(_target.position); // Заставляем агента двигаться в сторону _target'а
if (Vector3.Distance(_agent.transform.position, player.transform.position) < 100) { transform.LookAt(pos); _target = player.transform; }
else { _target = _home; }
if (Vector3.Distance(_agent.transform.position, player.transform.position) < 50)
{ _agent.speed = 0; }
else { _agent.speed = 3.5f; } } }
|
|
| |
beril | Дата: Среда, 05 Августа 2015, 19:43 | Сообщение # 4 |
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
| Реализация волнового алгоритма нахождения кратчайшего пути к динамически движущимся объектам глянь эту статью, недавно появилась. Может, что то поможет
Накодил? Убери за собой! Инвентарь в Unity(UI) Инвентарь в Unity(GUI)
|
|
| |
Tymonr | Дата: Среда, 05 Августа 2015, 20:27 | Сообщение # 5 |
With OpenSource forever♥
Сейчас нет на сайте
| beril, довольно-таки неэффективный алгоритм получается, при сотне-другой таких ИИ на поле все скатится к жутчайшему проседанию фпс
Если вы решили обратиться к нам за помощью, не становитесь в позицию неудачника. И не ведите себя как неудачник. Лучший способ получить быстрый и чуткий ответ, - спрашивать как победитель — спрашивать как человек умный, уверенный в себе и знающий, которому просто понадобилась помощь при решении одной конкретной проблемы. Как правильно задавать вопросы в технических форумах
|
|
| |
beril | Дата: Среда, 05 Августа 2015, 22:15 | Сообщение # 6 |
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
| Цитата Tymonr ( ) beril, довольно-таки неэффективный алгоритм получается, при сотне-другой таких ИИ на поле все скатится к жутчайшему проседанию фпс Ну там пример только, самому можно дальше допилить
Накодил? Убери за собой! Инвентарь в Unity(UI) Инвентарь в Unity(GUI)
|
|
| |
|