Пятница, 29 Марта 2024, 18:25

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Выделение ГО (всякие-разные вопросы)
Выделение ГО
polousДата: Пятница, 22 Августа 2014, 11:32 | Сообщение # 1
частый гость
Сейчас нет на сайте
Ребята, вновь порция нубских вопросов, не обессудьте)

В сцене есть объекты - игроки, например, с тэгом "players". На данном нулевом этапе был создан примитив и на нем лежит скрипт Player и FindEnemy, который ищет врагов в поле зрения игрока. Методы скрипта FindEnemy запускаются в скрипте Player. Эта вся прелюдия просто для вашего понимания, что есть в сцене. Я создал копию игрока, соответственно, все что висит на первом игроке, то висит и на копии. Для дальнейшего продвижения в написании игры мне нужно в игре как-то обращаться к конкретному игроку, например, по клику мышки или по нажатию кнопки "next player" на экране. Можете дать советы, как это сделать? Как выделить (не подкрасить при наведении или клике мышки, а именно выделить) объект в сцене?
Правильно ли я рассуждаю?
1) сначала нужно "запихнуть" (как это сделать??) все имеющиеся объекты с тэгом "players" в массив (если "да", то где это лучше делать - в отдельном скрипте или в скрипте Player, или это вообще не принципиально?)
2) рэйкастить из курсора мышки в сцену и по клику получать инфу об объекте (можно ли вообще так рэйкастить из мышки? или можно только из таргета камеры? и как узнать по рейкасту, что это именно объект [1] из массива players, а не [100500]?
3) когда получили от рейкаста инфу, что это именно тот ГО, то уже делаем что-то с этим ГО

правильная логика? или лучше/оптимальнее использовать какие-то другие способы?


Сообщение отредактировал polous - Пятница, 22 Августа 2014, 11:34
MANMANAДата: Пятница, 22 Августа 2014, 12:28 | Сообщение # 2
почти ветеран
Сейчас нет на сайте
рейкастишь из любой точки, объекта, обычно рейкстится из камеры в точку клика или позиции мыши. сравниваешь, то во что ткнул, пробегая по всему массиву hit.tranform.... = array element, если из массива делаешь с этим объектом что хочешь
только зачем что-то записывать в массив, если объектам можно дать теги и по тегам if(hit.transform.tag) == "yourTag"){...} смотреть, интересует тебя объект или нет
вместо трансформ монешь использовать GameObkect: hit.gameObject.tag, Destroy(hit.gameObject)...
Если же среди объектов с одинаковым тегом нужно выделить какой-то определенный объект, то ID объекта/инстанса тебе в помощь


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Пятница, 22 Августа 2014, 12:54 | Сообщение # 3
частый гость
Сейчас нет на сайте
Ок, спасибо за ответ, MANMANA!
Сразу возникает следующий вопрос (на понимание) - игра предполагается пошаговой, т.е. игрок первый потратил очки действия и ход переходит к следующему игроку. Вариант выбора по клику мышки мы обсудили выше. И ты предлагаешь выбирать по ID. Но ведь если реализовывать переход хода от одного к другому, когда кончились очки действия, то по ID не получится (я предполагаю). И здесь логичнее сделать массив и последовательно переходить от одного компонента массива (игрока) к другому, верно? Если это так, то
1) как сделать массив из уже созданных в сцене объектов?
2) как с помощью рейкаста у объектов в массиве с одинаковым тэгом узнавать их номер в массиве? ... хотя, видимо, и тут их можно по ID отличать
MANMANAДата: Пятница, 22 Августа 2014, 13:33 | Сообщение # 4
почти ветеран
Сейчас нет на сайте
Хех
массив a - игроки твои;
массив b - игроки соперника;

игроки твои - теги "myBots"
игроки врага - теги "enemyBots"

Start() {
Инстанцируешь врагов
нашел все объекты с тегами своих - запихнул в массив a
нашел врагов по тегам - запихнул врагов массив b
}

Update {
твой ход - пробегаешь массив своих, ищешь у кого есть ходы,
берешь того, у кого есть ходы,
ходов нет - переход к другому своему дуфолтом, либо по кнопке перехода, либо по выбору мышью
ходов у твоих нет/нажата кнопка перехода хода? - берешь массив врага.
}

ответы на твои 1) запихиваешь их как GameObject в массив GameObjects

var a: GameObject[];
var b: GameObject[];

a = GameObject.FindGameObjectsWithTag("myBots");//как раз в старт можешь запихнуть, если в ходе одной сцены новые не будут появляться.
b = GameObject.FindGameObjectsWithTag("enemyBots");

ну и ссылку http://docs.unity3d.com/ScriptReference/GameObject.FindGameObjectsWithTag.html
ID можешь брать стандартный из Unity, либо сам писать при инстанциировании, либо при добавлении в массив


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею


Сообщение отредактировал MANMANA - Пятница, 22 Августа 2014, 13:36
polousДата: Пятница, 22 Августа 2014, 13:42 | Сообщение # 5
частый гость
Сейчас нет на сайте
ниче-ниче, однажды я дорасту до твоего уровня, MANMANA)) Спасибо тебе, который раз даешь бесценные советы) буду пробовать
MANMANAДата: Пятница, 22 Августа 2014, 14:14 | Сообщение # 6
почти ветеран
Сейчас нет на сайте
до моего уровня тебе недалеко, поверь мне smile я в деве совсем недавно
конечно, если есть желание познавать новое и создавать что-то.
а так, помнишь по Ахиллеса и черепаху? wink
на самом деле это не совсем верно, поскольку в бесконечности расстояние между ними не столь уж и значительное.
Как замечал Андрей Николаевич Пивоваров (хороший человек и преподаватель) на наши фразы, типа: "Поскольку V2 относительно мало, то ею можно пренебречь".
"Относительно чего оно мало?"


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Пятница, 22 Августа 2014, 15:25 | Сообщение # 7
частый гость
Сейчас нет на сайте
=) удивительно, но я совсем недавно открыл это желание) оказалось, что программировать очень увлекательно, сложно и интересно - крайне творческая работа - куча задач, которые могут решаться чуть ли не бесконечным числом способов! - это офигенно! Тем не менее, ты всегда будешь опытнее (при то же условии, что тебя не покинет желание познавать новое и создавать что-то ;)) и это хорошо, потому как учиться опыту у более опытных - наиболее верный вариант, спасибо, что помогаешь) ты хороший учитель
MANMANAДата: Пятница, 22 Августа 2014, 15:29 | Сообщение # 8
почти ветеран
Сейчас нет на сайте
спасибо, отвечаю на то, с чем сам сталкивался.

http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Пятница, 22 Августа 2014, 22:36 | Сообщение # 9
частый гость
Сейчас нет на сайте
Эх-ох, новые трудности

все та же сцена, на ней боты-игроки и боты-враги. У игроков есть область видимости. Если враг попал туда - виден, вне области - невиден. Когда в сцене один бот-игрок, я пробегаю по всем врагам и если кто-то попал в FOV, то он виден - все ок. Когда я добавляю цикл по всем игрокам, чтоб делали тоже самое, исполняет функцию поиска только последний в массиве бот-игрок. И я вообщем-то понимаю, что так и должно быть, т.к. вся инфа для предыдущих ботов-игроков затирается новой инфой для следующего в цикле бота-игрока... я это понимаю, но как организовать циклы, чтоб было так, как хочу, я не знаю... а хочется мне, чтоб у каждого бота-игрока был FOV, т.е. если один видит врага, то это не значит, что видит другой и тп... подскажете как исправить ситуацию?

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

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
      public static GameObject[] enemies;
      public static GameObject[] players;

      void Start () {
       enemies = GameObject.FindGameObjectsWithTag("Enemies");
       players = GameObject.FindGameObjectsWithTag("Players");
      }

      void Update () {
       GetComponent<FindEnemies>().EnemyFinder();
      }
}


второй скрипт
Код

using UnityEngine;
using System.Collections;

public class FindEnemies : MonoBehaviour {
      float distance;
      float angle;
      bool inFOV;

      public void EnemyFinder(){

       foreach (GameObject p in GameManager.players) {

        foreach (GameObject e in GameManager.enemies) {

         distance = Vector3.Distance (p.transform.position, e.transform.position);
         angle = Vector3.Angle (p.transform.forward, e.transform.position - p.transform.position);

         if (angle < p.GetComponent<Player>().aov & (int) distance < (p.GetComponent<Player>().dov) ) {
          inFOV = true;
         }
         else {
          inFOV = false;
         }
             

         if (inFOV) {
          e.renderer.enabled = true;
         }
         else {
          e.renderer.enabled = false;
         }
        }
       }
      }
}



Добавлено (22.08.2014, 21:20)
---------------------------------------------
может создать бул переменную для игрока, в которую будет сохраняться true, если враг попал в фов, тогда она не будет затираться.... unsure

Добавлено (22.08.2014, 21:36)
---------------------------------------------
наверное, даже нужно сделать 2д массив булов из колврагов х колигроков


Сообщение отредактировал polous - Пятница, 22 Августа 2014, 22:38
MANMANAДата: Пятница, 22 Августа 2014, 23:20 | Сообщение # 10
почти ветеран
Сейчас нет на сайте
Я бы сделал так, если враги - инстансы, то хранить в них массив того, кого они видят, причем как своих, так и чужих.
своих-чужих различать по тагу.
свои и чужие могут использоваться для разработки тактики атаки/обороны: например, расстановки и оценки сил.
не бежать же всей кучей на одного чужака, если сзади анализируемого инстанса стоит второй чужак.
а если вокруг первого чужака достаточно своих, и они способны с ним справиться, то лучше оставаться невидимым, либо пойти в разведку...

свои/чужие здесь использованы для обозначения врагов по отношению к юнитам игрока/игрокам, а также для обозначения юнитов игрока/игроков по отношению к врагу.
т.е. кто для кого - враг зависит от того, с какой стороны посмотреть. smile

Другой вариант, вешай на префаб врага скрипт FindEnemies.
Теперь у каждого инстанса алгоритм скрипта будет искать врагов и не нужно будет пробегать все свои ГО, а только чужаков.

Кстати, есть такой тип массива ArrayList(). Интересность заключается в том, что его размер может меняться, причем добавление нового элемента всегда происходит В КОНЕЦ МАССИВА.
Последний обнаруженный чужой, как правильно - самый актуальный ;), поскольку тактика может в корне поменяться.
Есть и минусы - динамический массив ресурсозатратней массива с фиксированной длиной.
Но в данном случае размер массива роли играть не будет, врагов-то не миллионы.


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
ArtanielДата: Суббота, 23 Августа 2014, 12:46 | Сообщение # 11
частый гость
Сейчас нет на сайте
Не вполне понимаю зачем это вообще хранить по массивам, если оно используется один раз, сразу после расчета и в каждом новом фрейме пересчитывается заново.
Я б делал так.
Есть скрипт нашего игрока, в нем нужны aov и dov в публичных переменных.
Есть скрипт врага. Он действительно должен висеть на каждом враге, а значит быть включен в префаб врага, который мы инстантиируем, когда создаем нового врага.
Каждый враг только для самого себя перебирает наших игроков. Если хоть один его увидел - рендерер рисуется, иначе прячется.

Код

bool inFOV;
float distance;  
float angle;  

void Update(){
   inFOV = false; //пока не найдем того кто видит считаем что не видят.
   foreach (GameObject p in GameObject.FindGameObjectsWithTag("Players")) {   
     distance = Vector3.Distance (p.transform.position, transform.position);  
     angle = Vector3.Angle (p.transform.forward, transform.position - p.transform.position);  
     // поскольку это в скрипте противника, то можно брать значения своего transform
     if (angle < p.GetComponent<Player>().aov & (int) distance < (p.GetComponent<Player>().dov) ) {  
       inFOV = true;  
     } //иначе ничего не делаем, если там был false, он и остается. Если уже успел сменится на true, то ктото другой уже видит, значит должен быть true
   }
   //и только когда обошли всех кто мог видеть, в inFOV либо остался false в случае если не мог видеть никто, или true, если видел хоть ктото.
   if (inFOV) {  
     e.renderer.enabled = true;  
     }  
     else {  
     e.renderer.enabled = false;  
     }  
}


Считать GameObject.FindGameObjectsWithTag("Players") в скрипте противника или в менеджере - имхо не важно.
polousДата: Суббота, 23 Августа 2014, 19:34 | Сообщение # 12
частый гость
Сейчас нет на сайте
MANMANA, Artaniel, спасибо огромное! советы работают, код в последнем посте делает все, что мне хотелось, НО! Почему я написал о бул массиве - дело в том, что если придерживаться той логики, которую Artaniel изобразил в посте выше, то враг, если его видит хоть один из игроков, он виден для всех игроков... т.е. у него true и всё тут. Но ведь в игре будут ситуации, когда игрок видит один набор врагов, а другой игрок - других и при переходе от одного игрока к другому рендериться должны только те, что попадают в FOV текущего игрока (выбранного). Т.е. я это представляю себе так, что для каждого плеера должен быть отдельный обновляемый покадрово набор FOVов по каждому врагу. Это я, конечно, наперед забегаю, потому как сейчас нет никакого выделения игроков, а следовательно скрипт, представленный выше - это именно то, что я хотел. Хотя мне вскоре предстоит столкнуться с описанной проблемой, когда будет выбор игроков реализован.

Добавлено (23.08.2014, 19:34)
---------------------------------------------
итак, все-таки поднимаю этот вопрос. Например, есть 2 игрока и 2 врага. Один игрок "видит" сразу двоих, а другой только одного. Согласно последнему скрипту все враги будут видимы, тк скрипт для врагов сохраняет либо тру, либо фолс, и тк цикл по всем игрокам дает инфу, что по совокупности все враги в поле зрения, то у каждого из них тру. Нужно реализовать более сложный вариант, где у бота может быть тру для одного, но фолс для другого. Есть идеи? Все-таки бул массив или как-то иначе? просто совет/подсказку/наводку, весь скрипт писать не нужно)) а то вы так за меня всю игру напишете happy

MANMANAДата: Воскресенье, 24 Августа 2014, 14:50 | Сообщение # 13
почти ветеран
Сейчас нет на сайте
если скрипт вешать на !префаб! врага/игрока, то для каждого игрока/врага будет свой массив того, кого он видит.
обработку делать на анализе этих массивов.
не забывай про префаб. также можно использовать вариант Артаниэля, если не нужно хранить видимость тех или иных врагов.
правда зачем статикой - не понятно, можно забирать инфу из скрипта через GetComponent(...).variable


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
ArtanielДата: Понедельник, 25 Августа 2014, 23:22 | Сообщение # 14
частый гость
Сейчас нет на сайте
Цитата polous ()
. Нужно реализовать более сложный вариант, где у бота может быть тру для одного, но фолс для другого.


polous, я честно запутался что ты пытаешься сделать. Ты правильно расписал о том как это можно хранить, 2-мерный массив bool-ов - вполне удачный вариант, лишь бы за 1 фрейм успевало все посчитать. Но я уже говорил что не нужно все хранить, если ты его можешь использовать сразу, как только посчитал.

Я подумал, тебе нужно выводить на экран тех противников, которые видны, хотябы одним юнитом игрока (ты их своими игроками называешь на сколько я разобрался). В таком случае хранить незачем, кого надо показываем, кого не надо прячем. А в следующем фрейме всё равно всё заново считать.

Если нам нужно знать кто из своих персонажей видит сколько врагов, мы можем сделать практически такой же скрипт на каждом своем персонаже. Только он будет не показывать-прятать, а накапливать количество увидинных противников и чтото с ним сразу делать.

Или мы вообще делаем мультиплеер? Это отдельная ситуация и с точки зрения видимости даже проще, на каждом конкретном клиенте нас волнует только то что видит этот один игрок. Но вылазит куча других вопросов.
polousДата: Вторник, 26 Августа 2014, 00:32 | Сообщение # 15
частый гость
Сейчас нет на сайте
Да вроде бы все получилось, что хотел сделать. В твоем варианте скрипта поиска врагов я в цикл по юнитам игрока добавил одномерный массив бул переменных, который дает инфу о видимости для каждого из игроков. Т.к. в игре обнаруженные враги в любом разе будут отображаться для всех юнитов игрока, то твой вариант кода я и использовал. А добавил я массив для того, чтобы невидимым врагам (для определенных юнитов игрока) задавать уникальные свойства, например, невозможность стрелять по нему тем игроком, который его не видит.
Вроде как я со всеми вопросами разобрался, поэтому тему можно считать закрытой. Всем спасибо за оказанную помощь!


Сообщение отредактировал polous - Вторник, 26 Августа 2014, 00:32
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Выделение ГО (всякие-разные вопросы)
  • Страница 1 из 1
  • 1
Поиск:

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