На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Предназначение данного раздела
Данный раздел предназначен для публикации уроков и примеров по разработке компьютерных игр любого сорта, в том числе авторских проектов участников нашего форума. Главное условие публикации: необходимо не только выложить свое творение, но и подробно описать процесс его создания, подводные камни и прочие, интересные для собрата-разработчика, вкусности.

Если вы желаете выложить свой проект - пишите в Общеорганизационную тему. Есть какие-то другие вопросы по делу - туда же.

Модераторы: Da$aD
  
> [MMORPG своими руками] Часть X.3, Организация GUI приложения на Unity
    Организация GUI приложения на Unity

    Несмотря на то, что Unity больше заточен под 3d приложения, сделать на нем 2d не так уж и тяжело.
    Для начала разберемся с архитектурой. Каждую 2д сцену или "окно" будет описывать один скрипт, внутри которого в методе OnGUI будет отрисовываться это самое GUI. Примеры отрисовки можно прочитать тут: http://unity3d.com/support/documentation/Components/GUI%20Scripting%20Guide.html

    Каждый такой скрипт мы прилепим к отдельному GameObject размещенному на сцене. Это понадобиться нам для show/hide над окнами. Дело в том, что меняя свойство active (boolean) у любого объекта мы активируем и деактивируем и его "детей", в том числе прикрепленные к нему скрипты, а значит может активировать или деактивировать конкретное окошко.

    теперь переходя от теории к практике, напишем скрипт WindowsManager, который будет у нас инкапсулировать описанную выше логику. Для начала надо зарегистрировать используемые окна:
    ExpandedWrap disabled
      /**
          Зарегистрировать новое "окно"
          @param name имя-идентификатор окна
          @param window объект, содержащий компоненты окна
      */
      function RegisterWindow(name : String, window : GameObject){
          var window_data : Array = new Array();
          window_data.Push(name);
          window_data.Push(window);
          mWindows.Push(window_data);
      }

    Т.е. мы сохраняем соотвествия, имя окна - объект, содержащий скрипт GUI. Рассмотрим тут два момента.
    Во-первых, в самом Unity есть функция поиска игровых объектов по их имени. Казалось бы зачем велосипед строить? Проблема в том, что функция ищет объект в списке только активных объектов, а так как все кроме текущего "окна" деактивированы, то она работать не будет :(
    Во-вторых, строковой идентификатор может показаться слишком тяжелом, однако переключения окон будут происходить не часто и никакого выйгрыша производительности за счет.

    Теперь, чтобы отобразить окно достаточно использовать метод:
    ExpandedWrap disabled
      /**
          Показать окно с данным именем
          @param name имя-идентификатор окна
      */
      function ShowWindow(name : String){
          if(mCurrentWindow != null){
              mCurrentWindow[1].active = false;
          }
          
          for(var i : int = 0; i < mWindows.length; i++){
              if(mWindows[i][0] == name){
                  mCurrentWindow = mWindows[i];
                  mCurrentWindow[1].active = true;
              }
          }
      }


    Отдельным особняком я сделал отображение ошибок, чтобы не делать отдельное окно, тот же менеджер сам умеет отображать ошибки.
    ExpandedWrap disabled
      /**
          Показать окно с сообщением об ошибке
          @param err_msg сообщение об ошибке
      */
      function ShowError(err_msg : String){
          mCurrentWindow[1].active = false;
          mIsError = true;
          mErrorMessage = err_msg;
      }

    И вот сам код отрисовки ошибки
    ExpandedWrap disabled
      function OnGUI(){
          if(mIsError){
              GUI.BeginGroup (Rect (150,125, 300, 200));
                  GUI.Box (Rect (0,0,300 ,200), "ERROR");
                  GUI.TextArea (Rect (5, 30, 290, 135), mErrorMessage);
                  if(GUI.Button (Rect (100,170,100,25), "OK")){
                      mCurrentWindow[1].active = true;
                      mIsError = false;
                  }          
              GUI.EndGroup ();    
          }
      }


    Текстовые таблицы

    Одной из не маловажных проблем игры является встраивание мультиязычности приоложения. И возможности менять ее на лету (На сайтах игр часто расположены флаги государств, нажимая на которые, можно менять язык сайта).

    Для этого были организованы текстовые таблицы. Добавляем все варианты строки. Нам возвращают идентификатор строки, который является индексом в массиве записей. Тут уже скорость важна, т.к. общение к строкам идет в каждом кадре.
    ExpandedWrap disabled
      /**
          Регистрация новой текстовой строки
          @ru русский вариант строки
          @ge немецкий вариант строки
          @en английский вариант строки
          
          @return идентификатор строки
      */
      function RegisterString(ru : String,ge : String, en : String){
          var record : String[] = new String[3];
          record[0] = ru;
          record[1] = ge;
          record[2] = en;
          var id : int = mTextTable.length;
          mTextTable.Push(record);
          return id;
      }

    Чтобы получить нужную строку в нужном переводе, достаточно использовать функцию:
    ExpandedWrap disabled
      /**
          Получить строку с нужным переводом
          @param идентификатор строки
          
          @return строка с нужным переводом
      */
      function GetTextString(id : int){
          var record : String[] = mTextTable[id];
          if(record == null){
              return "#UNKNOWN STRING#";
          } else {
              return record[mCurrentLang];
          }
      }

    mCurrentLang - идентификатор текущего используемого языка. Для смены языков у меня применяются методы:
    ExpandedWrap disabled
      /**
          Установить русский язык
      */
      function SetRussianLang(){
          mCurrentLang = 0;
      }
       
      /**
          Установить немецкий язык
      */
      function SetGermanLang(){
          mCurrentLang = 1;
      }
       
      /**
          Установить английский язык
      */
      function SetEnglishLang(){
          mCurrentLang = 2;
      }
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script Execution time: 0,0868 ]   [ 18 queries used ]   [ Generated: 21.11.18, 16:23 GMT ]