Saturday, March 2, 2013

Задача 2: Отображение «хотспотов» для объекта в Unity3d


Практическое использование движка Unity3d.





Задача 2: Отображение «хотспотов» для объекта в Unity3d



Содержание


  • Задача 2: Отображение «хотспотов» для объекта в Unity3d.
  • Получение списка комнат
  • Отображение хотспотов

Задача 2: Отображение «хотспотов» для объекта в Unity3d.

 Теперь давайте рассмотрим следующую задачу: необходимо продемонстрировать «хотспоты» для комнат. Эта статья является продолжение работы первой статьи.
http://denis-potapenko.blogspot.com/2013/02/unity3d_407.html 
 Поэтому перед началом этой статьи желательно прочесть первую. В результате мы должны получить следующее:
Рис. В.

Получение списка комнат

Для получение списка комнат создадим массив названий комнат.
 private string[] mGORoomsNames = new string[] 
    {
        "Room0",
        "Room1",
        "Room2"
    };
Названия комнат мы можем получить, посмотрев в окно «Hierarchy» показанное на рис. 1.1.
Рисунок 1.1. – Список названий комнат


Также создадим переменную, которая будет в себе содержать список GameObject’ов комнат.

private List < GameObject > mGORooms = new List < GameObject >();

В методе «Start» получим GameObject’ы комнат.
foreach (var item in mGORoomsNames)
      {
          GameObject goRoom = GameObject.Find(item);
          mGORooms.Add(goRoom);
      }

Отображение хотспотов

 Создадим константы, которые будут хранить ширину и высоту хотспота.

private const float cHotspotSizeX = 70;
private const float cHotspotSizeY = 24;

 А теперь создадим функцию OnGUI, с помощью которой Unity3d будет отображать UI. В начале этой функции создадим временную переменную, которая будет хранить положение текущего хотспота.

Rect tmpRect = new Rect();

Хотя для наглядности я инстанцировал класс «Rect» прямо в функции OnGUI, я крайне рекомендую создавать переменные такого рода, как переменные члены класса и выделять память им там же. Причина в том, что Вам приходится инстанцировать класс каждый раз при вызове метода «OnGUI». Конечно, теоретически сборщик мусора должен будет освободить выделенную память, но, во-первых, я встречал случаи, когда сборщик мусора по каким-то причинам этого не делает, а во-вторых, потому что фрагментация памяти это всегда не очень хорошо.
Далее, для каждой комнаты определим ее позицию в трехмерном пространстве.

// get position of room in 3d space
Vector3 roomPos = goRoom.transform.position;

Теперь определим позицию этого же объекта на экране. Для этого конвертируем трехмерную координату в координаты окна (в двухмерные координаты).
// convert room position from 3d space to screen space (2d)
Vector3 hotSpotPos = Camera.mainCamera.WorldToScreenPoint(roomPos);
Также необходимо вычислить прямоугольник для отображение текущего хотспота. Вычисление очень простое: позиция – это позиция объекта минус половина от размера хотспота.
// calculate rect for rendering label
tmpRect.x = hotSpotPos.x - cHotspotSizeX / 2;
tmpRect.y = Screen.height - hotSpotPos.y - cHotspotSizeY / 2;
tmpRect.width = cHotspotSizeX;
tmpRect.height = cHotspotSizeY;
Наконец, отображаем хотспот.
// now render label at this point
GUI.Box(tmpRect, mGORoomsNames[i]);
Хочу отметить, что даже при вращении, перемещении и масштабировании объектов, хотспоты останутся соответствующих местах.

Посмотреть результаты работы можно посмотреть здесь:
https://dl.dropbox.com/u/20023505/Articles/Unity3d/Lesson2/WebPlayer/WebPlayer.html


Исходный код здесь:

https://dl.dropbox.com/u/20023505/Articles/Unity3d/Lesson2/Sources/Sources.zip
https://github.com/den-potapenko/Unity3dArticles/tree/master/Lesson2




No comments:

Post a Comment