Saturday, March 2, 2013

Task #2: Rendering hotspots in Unity3d


Practical use of Unity3d engine.




Task #2: Rendering hotspots in Unity3d


Contents

  • Task 2: Rendering hotspots in Unity3d. 
  • Get rooms list 
  • Rendering hotspots


Task 2: Rendering hotspots in Unity3d.

In this article we will solve next task: we need to display hotspots for rooms. This article is base on first one (http://denis-potapenko.blogspot.com/2013/02/task-1-rotate-pan-and-zoom.html). So, I strongly suggest reading the first article. As result, we want to achieve is shown on Figure:

Figure B.


Get rooms list

To get list of rooms, at first, create an array of rooms’ names.
private string[] mGORoomsNames = new string[]
{
    "Room0",
    "Room1",
    "Room2"
};

Names of rooms we can get from «Hierarchy» window shown in Fig. 1.1.

  

Figure 1.1. – Rooms’ names

Also, let’s create variable containing list of rooms’ GameObjects.
private List<GameObject> mGORooms = new List<GameObject>();
In «Start» function, get rooms’ GameObjects.
foreach (var item in mGORoomsNames)
{
    GameObject goRoom = GameObject.Find(item);
    mGORooms.Add(goRoom);
}

Rendering hotspots

Create constants for hotspots’ width and height.
private const float cHotspotSizeX = 70;
private const float cHotspotSizeY = 24;
And now, create OnGUI function. Unity3d uses this function for rendering UI. At the start of this function create temporary variable, which will store current hotspot position.
Rect tmpRect = new Rect();
Although, for clarity, I instantiated class “Rect” right in “OnGUI” function, I highly recommend for such purpose to instantiate class variables immediately in class declaration. The reason is that the application will instantiate the class every time when “OnGUI” function called. In theory, the garbage collector will release the allocated memory, but, at first, I have seen when garbage collector for some reason doesn’t do it, and secondly, because memory fragmentation is not very good.
Next, let’s determine rooms’ positions in three-dimensional space.
// get position of room in 3d space
Vector3 roomPos = goRoom.transform.position;
Now, let’s determine position of this object on the screen. To do this convert three-dimensional coordinate to screen coordinates (two-dimensional coordinate).
// convert room position from 3d space to screen space (2d)
Vector3 hotSpotPos = Camera.mainCamera.WorldToScreenPoint(roomPos);
Also, we need to calculate rectangle for hotspot rendering. Calculation is very simple: position – it’s object’s position minus size of hotspot.
// 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;
Finally, render hotspot:
// now render label at this point
GUI.Box(tmpRect, mGORoomsNames[i]);
I should mention, that hotspot will be rendered it proper position even when object rotates, pans or zooms. 
Results of development you can see here:
https://dl.dropbox.com/u/20023505/Articles/Unity3d/Lesson2/WebPlayer/WebPlayer.html

Source code you can download from here:
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