Пятница, 22 Ноября 2024, 09:45

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Создание 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, довольно-таки неэффективный алгоритм получается, при сотне-другой таких ИИ на поле все скатится к жутчайшему проседанию фпс

Ну там пример только, самому можно дальше допилить smile




Накодил? Убери за собой!
Инвентарь в Unity(UI)
Инвентарь в Unity(GUI)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг