How to make a mini map for your scene in unity3d this is my first tutorial on unity, kinda nervous writing it... anyway have you guys ever play hitman, dynasty warrior, Starcraft or any RTS games? Usually at the bottom left of those games, there's a 2D map showing where the players are and where you're suppose to go etc. well, that's what I'm trying to write about today, how to make a simple
Mini map similar to that, instead of using the top down camera method.
This comes in handy when you're trying to create a mini map to locate
The player and the enemies (AIS) Current position... like hitman, where
You can see where everyone's heading from within a map.
I 've already set up the scene for an easy start, download it here:
Starting project
Final project
And... let's get started!
First, import the "startpackage" into unity, then expand the "my scenes"
Folder in the project view and open up the "Tut" scene. There shocould be
A "well" textured terrain with mountains, a prefab called "enemy" in
The form of a cube, a first person controller, and a game object called
"Waypoints" which contains a bunch of other game objects with "W" follow
By a number on their name inside. Click "play" to play the scene, and
You shoshould see the cube starting to move by itself each SS all
Waypoints in the scene.
next, create a new Javascript file, name it "minimapscript" (or whatever
that suits you ). double click on it in the project view to edit it. now
we are gonna create a few variables for the script (comments are added
for explanation):
// for placing the image of the mini map.
var minimap: guistyle;
// two transform variables, one for the player's and the enemy's,
var PLAYER: transform;
var enemy: transform;
// icon images for the player and enemy (s) on the map.
var playericon: guistyle;
var enemyicon: guistyle;
// offset variables (X and Y) -Where you want to place your map on screen.
var mapoffsetx = 762;
var mapoffsety = 510;
// the width and height of your map as it'll appear on screen,
var mapwidth = 200;
var mapheight = 200;
// width and height of your scene, or the resolution of your terrain.
var scenewidth = 500;
var sceneheight = 500;
// the size of your player's and enemy's icon on the map.
var iconsize = 10;
private var iconhalfsize;
Function Update (){// So that the specified point of the icon is at the middle of the image.// You'll know what it means later...Iconhalfsize = iconsize/2;
}
Those were the basic variables required to make the map works. You can
Try dragging the script to the FPS (First Person Controller) and then
Customize the guistyle variables with the textures I provided in
Folder named "My Textures"; drag the enemy from the hierarchy view
The "enemy" transform variable in the FPS's Mini map script, and
Same thing for the FPS, into the "Player" transform variable.
Now there's a few thing you need to understand before we proceed...
So what we are trying to do here is to take the X and Z (not y) Position
Of both the player and enemy, and convert them into the X and Y (again,
Not Z) axis of the screen (for the map). When
You look at the image above. It's like you're gonna flip the whole
Things Up (Z and X to Y and X). I'm not sure if unity has a function
What I just mentioned above, I know there's something called
Gui. matrix4x4, but at the moment I was to lazy to find out, and I used
The directly proportional method, to "convert them". Under the UPDATE function, add this line: function getmappos (POS: float, mapsize, scenesize) {return POS * mapsize/scenesize ;}
Basically what this line of function does is to take the position (POS)
Of the player, multiply by the height or width of the map, and then
Divide by the resolution (height or width) of the terrain, and it'll
Return back a value which we cocould use later to locate the player's
Position as it is on the map. after that, create a new ongui function below the getmappos function, write these in: function ongui () {GUI. begingroup (rect (mapoffsetx, mapoffsety, mapwidth, mapheight), minimap); var PX = getmappos (transform. position. x, mapwidth, scenewidth); var PZ = getmappos (transform. position. z, mapheight, sceneheight); var playermapx = PX-iconhalfsize; var playermapz = (PZ *-1)-iconhalfsize) + mapheight; GUI. box (rect (playermapx, playermapz, iconsize, iconsize), "", playericon); GUI. endgroup ();}
The first line (GUI. begingroup) and the last (GUI. endgroup) is to create
A Gui group and placed it at the bottom right of the screen using
Mapoffsetx and mapoffsety variables in rect (), and the GUI texture
It wocould be the minimap guistyle which we just set-up earlier. the second and third line (PX and PZ) is two new variables which has the returned value of the getmappos function... the forth line (playermapx) contains the information of the player's
X-axis position on the map. It is minus by iconhalfsize so that we can
Have the role point of the player's icon which wowould appear on the map
To be in the middle (looks more appropriate that way). The second th line (playermapz), like playermapx, contains the information
Of the player's Y position on the map (it's written as playermapz to let
You know that we are taking the player's Z-axis position in the scene,
You can name it to anything you want actually). Like what I 've mentioned in the sketch I posted above (the one with the Z
& X axis, and Y & X axis), when you are creating the map, you
Have to flip the z-axis in scene vertically to make it the y-axis in
Map. To do that, we multiply "PZ" with negative one (which wowould flip
It), and then plus the mapheight to get the value of the Y-axis in map. The sixth line is to create a GUI. Box which wowould represent the player
On the map, together with the playericon guistyle as the texture... those stuff shocould be enough by now. Click "play" and you shocould be able
To see a map on the screen, and a small, yellow, diamond-shaped icon on
The map (the player). Try to move around, and you shoshould see the yellow icon move along too.
If it didn't, check your line again, see if you didn't confuse the Z
Axis with the Y axis (unless if you choose to write it accordingly,
Instead of copy and paste). if you understand what I 've wrote thus far, you should be able to code
The enemy part yourself. But if you can't, below is the full codes, copy
And paste them to your script:
// For placing the image of the mini map. VaR minimap: guistyle;
// Two transform variables, one for the player's and the enemy, VaR PLAYER: transform; var enemy: transform;
// Icon images for the player and enemy (s) on the map. VaR playericon: guistyle; var enemyicon: guistyle;
// Offset variables (X and Y)-Where you want to place your map on screen. VaR mapoffsetx = 762; var mapoffsety = 510;
// The width and height of your map as it'll appear on screen, VaR mapwidth = 200; var mapheight = 200;
// Resolution (both width and height) of your terrain. VaR scenewidth = 500; var sceneheight = 500;
// The size of your player and enemy's icon as it wocould appear on the map. VaR iconsize = 10; var iconhalfsize; function Update () {iconhalfsize = iconsize/2;} function getmappos (POS: float, mapsize: float, scenesize: Float) {return POS * mapsize/scenesize;} function ongui (){
// Everything about the map. Gui. begingroup (rect (mapoffsetx, mapoffsety, mapwidth, mapheight), minimap); var PX = getmappos (transform. position. x, mapwidth, scenewidth); var PZ = getmappos (transform. position. z, mapheight, sceneheight); var playermapx = PX-iconhalfsize; var playermapz = (PZ *-1)-iconhalfsize) + mapheight; GUI. box (rect (playermapx, playermapz, iconsize, iconsize), "", playericon); var SX = getmappos (enemy. transform. position. x, mapwidth, scenewidth); var SZ = getmappos (enemy. transform. position. z, mapheight, sceneheight); var enemymapx = SX-iconhalfsize; var enemymapz = (SZ *-1)-iconhalfsize) + mapheight; GUI. box (rect (enemymapx, enemymapz, iconsize, iconsize), "", enemyicon); GUI. endgroup ();}
And that's basically all... if you have any question (like an error or
Bug), drop me a message at leezhifei168@rocketmail.com, I'll try
Answer to your problem as soon as I can.
Please be noted the final product will not look like one of in GTAs, but
those in RTS games, where you have an entire big area in a small map.
to do the effect like in GTA, you have to use a top down camera and some
shaders, i'll try to post a tutorial about it later when I'm free.