Пару вопросов для юнитиводов от фазеровода :)

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 07 июл 2020, 13:13

Привет.

Хочу попробовать немного изучить unity, и столкнулся с проблемой в понимании некоторых базовых принципах работы.
Вот хотел бы пообщаться с опытными юнитиводами, дабы прояснить для себя некоторые практические моменты логики.
Работал с фазером, поэтому приведу практический пример работы с ним. Да и яваскрипт крайне хорош в плане чтения синтаксиса для c# программистов.

В фазере есть некая условная сцена, внутри которой создаются условные обьекты.

У сцены есть методы, они аналогичны методам в классах обьектов unity (Start,update...)
У фазера же вмето Start
preload
create
update - аналогичен

Допустим я хочу обьявить обработчик каких то там тапов/кликов.
Сначала я создам сцену
Синтаксис:
Используется javascript
myScene...... = function(){
 ....
}

Теперь у меня есть сцена со всякими там встроенными методами.

Допустим я хочу вывести координату обьекта на сцене. Простая функция, которая принмиает на вход некий условный игровой обьект и выводит в консоль его свойства.
Синтаксис:
Используется javascript
function getXY(obj){
     console.log(obj.x+" - "+obj.y);
}
 


Теперь для обьекта myScene я просто обьявляю глобальный обработчик событий (input).
Синтаксис:
Используется javascript
myScene.input.on("gameobjectdown", function(pointer, obj){
   getXY(obj);
}
 

Теперь в pointer у меня множество данных, в числе которых позиция игрового мира, учитывающая scale, offset, rotate.... и много чего еще
А в obj - игровой обьект со всеми его свойствами, если именно по нему произведен клик.

Я попробовал воспроизвести подобное в unity, и сразу же столкнулся с непониманием его принципов.
Можно ли обьявить какой то глобальный обработчик вне игрового обьекта?

Допустим нельзя.
Можно ли создавать игровой обьект из скрипта, с уже присвоенным ему обработчиком?

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

Разьясните пожалуйста.
Заранее спасибо откликнувшимся!
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение Woland 07 июл 2020, 13:36

Тут есть несколько вариантов.
Например, есть статические классы и методы, которые могут работать без как-либо объектов (то есть их не надо переносить на сцену). Полезно для каких-нибудь глобальных контроллеров (синглтон).

Или же надо создавать какой-нибудь контроллер, который занимается нужным функционалом. К примеру, тебе нужно программно нагенерить на сцене деревья. Создаешь пустой объект, называешь его Tree_generator_controller, вешаешь на него свой скрипт, который генерит при старте деревья. Ну или можешь запускать его не в Playmode, а во время редактирования сцены)
Woland
Адепт
 
Сообщения: 1240
Зарегистрирован: 20 апр 2013, 18:09
  • Сайт

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 07 июл 2020, 15:57

Woland писал(а):Тут есть несколько вариантов.
Например, есть статические классы и методы, которые могут работать без как-либо объектов (то есть их не надо переносить на сцену). Полезно для каких-нибудь глобальных контроллеров (синглтон).

Или же надо создавать какой-нибудь контроллер, который занимается нужным функционалом. К примеру, тебе нужно программно нагенерить на сцене деревья. Создаешь пустой объект, называешь его Tree_generator_controller, вешаешь на него свой скрипт, который генерит при старте деревья. Ну или можешь запускать его не в Playmode, а во время редактирования сцены)


То-есть можно видеть свойства одного обьекта из другого?
Но на сколько я знаю нельзя к примеру управлять обьектом light из камеры.
Как тогда пустой обьект может управлять другими обьектами?
Я че то не могу пока понять простых вещей.
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение Woland 07 июл 2020, 16:20

Из одного объекта можно спокойно получать свойста другого объекта. По сути ты хранишь ссылку на компонент и по этой ссылке можешь обращаться к нему.
Можешь задать ссылку в инспекторе
Синтаксис:
Используется csharp
[SerializeField]
SomeComponent comp;
......
comp.DoSomething();
comp.someField="SDAD";
myField=comp.someField;
 


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

Пример по поводу света - делаешь скрипт, к примеру LightController, вешаешь его на камеру (или на другой объект), в скрипте пишешь:
[SerializeField]
Light myLight.

В инспекторе указываешь этот компонент (перетаскиваешь туда со сцены объект со светом). Потом в скрипте управляешь параметрами света.
Woland
Адепт
 
Сообщения: 1240
Зарегистрирован: 20 апр 2013, 18:09
  • Сайт

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 07 июл 2020, 17:25

Woland писал(а):Из одного объекта можно спокойно получать свойста другого объекта. По сути ты хранишь ссылку на компонент и по этой ссылке можешь обращаться к нему.
Можешь задать ссылку в инспекторе
Синтаксис:
Используется csharp
[SerializeField]
SomeComponent comp;
......
comp.DoSomething();
comp.someField="SDAD";
myField=comp.someField;
 


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

Пример по поводу света - делаешь скрипт, к примеру LightController, вешаешь его на камеру (или на другой объект), в скрипте пишешь:
[SerializeField]
Light myLight.

В инспекторе указываешь этот компонент (перетаскиваешь туда со сцены объект со светом). Потом в скрипте управляешь параметрами света.


Да, про SerializedField я уже где то читал. Спасибо!

У unity нет встроенных событийных таймеров?
Задаю время через которое нужно выполнить функцию с передачей аргументов, и по истечению таймера он эту функцию выполняет, или все это требуется самому писать?

Еще у меня вопрос по update.
Вот взять те же временные функции. Получается что если я пишу таймеры, то код таймера всегда должен находиться внутри функции update?
https://metanit.com/sharp/tutorial/11.9.php
То-есть я не могу просто взять System.Threading и использовать его Timer?

Вообще, почему я это спрашиваю. Я так понимаю что функция update завязана на FPS, то-есть она вызывается один раз за один кадр. Получается, что я не могу использовать внешний таймер, так как может произойти потеря синхронизации. Получается должны быть встроенные таймеры.

С другой стороны, получается, что любые функции, которые завязаны на событиях и времени должны находиться в функциях update. Это верное утверждение?
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение Woland 07 июл 2020, 18:35

Есть Invoke(string methodName, float time);
Указываешь имя метода и время, через сколько запустить.

Есть Coroutine (https://docs.unity3d.com/ru/2019.4/Manu ... tines.html), там можно использовать yield return new WaitForSeconds(секунды).

Про Update - да, он выполняется в каждом кадре, поэтому для функционала со временем либо надо использовать Time.deltaTime (разница между текущим и предыдущим кадром в секундах), либо FixedUpdate (по умолчанию срабатывает 50 раз в секунду).
Woland
Адепт
 
Сообщения: 1240
Зарегистрирован: 20 апр 2013, 18:09
  • Сайт

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 08 июл 2020, 12:37

Покрутил c#, и что не понравилось, так это работа со структурами данных.
Не подскажете, какие библиотеки просто и понятно решают вопрос работы с вложенными структурами?

На пример, в javascript я создаю обьект
Синтаксис:
Используется javascript
object = {
     row:"value",
     row2:{
          value1:"blablabla",
          value2:"dfdfdfdfdf"
     }
}
 

Есть обьект, внтури есть некая вложенность.
Теперь что бы получить значение я просто обращаюсь по ссылке
object[row2][value2];

Я так понял что в c# из коробки подобное не реализовать. Я нашел Dictionary, но там похоже можно только одномерные словари обьявлять, да и все это выглядит как то нагромождено что ли, не знаю. Может знаете какую то библиотеку которая реализует подобные подходы так же изящно и легко как это делает javascript при работе с подобными задачами?

Я подумал что может быть JSON сериализовать и десериализовать, но может есть что то более простое?
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение Dewa1s 08 июл 2020, 13:14

Шарп - статически типизированный язык программирования, поэтому так писать не рекомендуется.
Однако никто не мешает использовать анонимные типы:
Синтаксис:
Используется csharp
var obj = new
        {
            row = "value",
            row2 = new
            {
                value1 = "blablabla",
                value2 = "dfdfdfdfdf"
            }
        };

Но за пределы метода такое не передашь, да и вообще это весьма неудобно
Аватара пользователя
Dewa1s
Старожил
 
Сообщения: 564
Зарегистрирован: 26 дек 2011, 02:12

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение seaman 08 июл 2020, 13:47

'Псевдошарп'. Но принцип должен быть понятен.
Синтаксис:
Используется csharp
public class MyObject{
  public class Row2{
     public string value = "blablabla";
  }
  public string row = "value";
  public Row2 row2 = new Row2();
}
....
var myObject = new MyObject();
var value = myObject.row;
var innerValue = myObject.row2.value;


PS: почитайте уроки по шарпу...
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 08 июл 2020, 15:46

Dewa1s писал(а):Шарп - статически типизированный язык программирования, поэтому так писать не рекомендуется.
Однако никто не мешает использовать анонимные типы:
Синтаксис:
Используется csharp
var obj = new
        {
            row = "value",
            row2 = new
            {
                value1 = "blablabla",
                value2 = "dfdfdfdfdf"
            }
        };

Но за пределы метода такое не передашь, да и вообще это весьма неудобно

Я конечно понимаю, что не было задачи изменять данные, но я все же думал что это предполагается :)
Да, по всей видимости сериализация единственынй выход при работе с большими обьемами вложенности. C# в нее не умеет из коробки.
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение seaman 08 июл 2020, 15:50

не было задачи изменять данные

А что Вам мешает их менять? Ну, конечно при способе Dewa1s не получится. Но при нормальных способах - пожалуйста.
сериализация единственынй выход

Сериализация полностью заткнется при рекурсивном вложении
C# в нее не умеет из коробки.

Вы просто не знаете шарп.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 08 июл 2020, 19:13

seaman писал(а):Вы просто не знаете шарп.

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

Как в Javascript. Допустим у меня есть некие данные с некой неопределенной вложенностью.
Предположим что они пришли из JSON.
Я просто парсю встроенным методом, и получаю обьект, котоый по сути и визуально является и воспринимается как обычный обьект, свойства которого я могу вызывать/менять в очень простой и изящной форме.

Допустим диалог, этакое дерево, которое рендерит движок.

Синтаксис:
Используется javascript
var dialog={
        "Привет, как дела?":{
                media:media.mp3_ogg.dialog_1,
                del:true,
               
                //Если pass, то можно прокручивать кликом / прикосновением по экрану в момент вопроизведения медиа конвеера
                pass:true,
               
                //Если wait то игра не будет устанавливать атрибут pass автоматически
                wait:true,
               
                "Ого, расскажи ка в подробностях":{
                        media:media.mp3_ogg.dialog_2_exp,
                        //Если wait, то прервать нельзя
                        wait:true,
                        //Если внутри есть незаблокированные элементы, то данный элемент будет показан
                        // pass:true,
                        //Элемент будет удаляться после просмотра                   
                        del:true,
                        //Исключаем из рендера
                        // block:true,
                        "А они?":{
                                del:true,
                                "А, ну понятно тогда..":{
                                        //Элемент будет удален затем будет переход по ссылке
                                        del:true,
                                        go:"Привет, как дела?"
                                }
                        },
                        "Хехе":{
                                del:true,
                                "Ладно, ладно":{
                                        del:true,
                                        go:"Привет, как дела?"
                                }
                        },
                        "Кажется я все понял":{
                                del:true,
                                go:"root"
                        }
                },
               
                "И тебя поймали пираты?":{
                        "И что же они?":{
                                "А не было ли еще каких то историй?":{
                                        func:function(){
                                                dialog["Привет, как дела?"]["Ого, расскажи ка в подробностях"].block=false;
                                        },
                                        go:"root"
                                }
                        }
                },             
                "А, ну понятно тогда":{
                        del:true,
                        go:"root"
                }
        },
        "Просто уйти":{
                media:media.exit_mp3_ogg.exit,
                //Закрыть диалог
                quit:true,
                //Никогда нельзя перекликнуть данную медию
                wait:true
        }
}


Каким методом в # вы бы воспользовались?
Хранили в JSON, и использовали бы ньютона для доступа к значениям?
Или есть как вы уже дали понять - встроенные в натив шарпа методы?

Как обьявить подобную структуру или ее аналог и перебрать потом ключи?
Хелп :)
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение Woland 08 июл 2020, 19:36

Делаешь класс Диалог, Реплика, в каждом классе объявляешь нужные параметры (bool, int, смотря, что тебе надо). В Диалоге у тебя будет массив реплик, в самой реплике можешь сделать, чтобы она ссылалась на другую реплику и т.д.
В итоге у тебя будет структура вложенных объектов нужных тебе классов. Надо сначала понять, какая у тебя структура возможна, потом описать её в классах, и все, json на неё нормально ляжет.
Woland
Адепт
 
Сообщения: 1240
Зарегистрирован: 20 апр 2013, 18:09
  • Сайт

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение maddogmaycry 08 июл 2020, 19:46

Woland писал(а):Делаешь класс Диалог, Реплика, в каждом классе объявляешь нужные параметры (bool, int, смотря, что тебе надо). В Диалоге у тебя будет массив реплик, в самой реплике можешь сделать, чтобы она ссылалась на другую реплику и т.д.
В итоге у тебя будет структура вложенных объектов нужных тебе классов. Надо сначала понять, какая у тебя структура возможна, потом описать её в классах, и все, json на неё нормально ляжет.


Вы не могли бы привести пример?
maddogmaycry
UNец
 
Сообщения: 11
Зарегистрирован: 07 июл 2020, 11:59

Re: Пару вопросов для юнитиводов от фазеровода :)

Сообщение seaman 08 июл 2020, 20:07

Синтаксис:
Используется csharp
public class Phrase {
  public string text;
  public string media;
  public bool del;
  public bool pass;
  public bool wait;
  public Phrase[] nextPhrase;

  public Phrase ChooseNext(bool condition) {...}
}

public class Dialog {
  public Phrase startPhrase;
}


Надеюсь Вы понимаете, что это только данные. Тут же должны быть и методы, типа обозначенного во фразе для выбора следующей фразы.
Методы для отрисовки фраз лучше выделить отдельно, чтобы можно было их легко менять. Тоже самое для загрузки - отдельно. Чтобы можно было загружать из разных мест.

Ну и вообще - чтобы это было более-менее рабочей системой диалогов - тут надо еще думать...

Да, и еще. Для удобства геймдиза - придется писать расширение для редактора.

И еще добавление.
public string text;
лучше заменить на
public int idText;
И отдельно иметь словарь текстов. Тогда Вы легко сможете менять язык текста.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

След.

Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: GoGo.Ru [Bot] и гости: 33