- Home /
Drawing an overlay mini-map
Hi guys, as you can see from the picture, I'm trying to make the red sphere(indicator) on the Mini map to follow the movement of the first person controller on the actual terrain. I've seen a lot of post on doing it, but i don't want to do it the "place a camera ontop of the actual terrain and change the settings etc". I'm asked to use another method which is to map the coordinates of the terrain to the mini map as you can see i circled in the picture. and then from there make the sphere(indicator) move with another script. I really need answers. Please help me. ):
This is what I have currently when I click Play. All I need to do is make the red dot correspond to wherever the player went on the minimap. I did it this way because I was asked to make a minimap that shows the whole terrain and only wants the indicator to move. This was what I've been suggested. Or if you guys have a better solution which will not affect the performance to the VERY big terrain, it would be good to share with me. (: I hope this gives a clearer picture of what I'm doing. Real sorry for any confusion caused. Thanks for all the replies. Hope you guys can help me further. (:
"I really need answers ):" is a really bad question title. Please make the question titles descriptive of your questions so it's easier for other people with the same problem to find your question in the future.
$$anonymous$$elv how do you upload your picture image at here UnityAnswer why i cant upload even i paste http://www.freeimagehosting.net/tdtv8
it display [x alt text]
Answer by Novodantis 1 · Jun 22, 2010 at 12:27 PM
I'm guessing by using only one camera you mean the minimap is a pre-rendered texture that you are placing images onto at certain locations? I'm going to assume this is the method.
First place your level's top left corner at the world origin (makes things simpler). I will assume 1000x1000 units as a terrain size in this explanation.
Then get the x,y coordinates of the object you want to display on the minimap and multiply that by difference between your map size and minimap texture dimensions resolution. So lets say your minimap image is 200x200. Your minimap coords should be their x,y positions in the scene multiplied by 0.2
To get their final screen position, simply add the coordinate of the minimap to their x,y counterpart. So if your minimap is bottom right (say at 590,390), add that value to all the x,y positions.
Use these co-ords to draw a 2DTexture image for each object on top of your minimap picture.
This should get you a basic, slightly old-skool image-based minimap for the whole level (scrolling would require a little more complexity, but not impossible). If you want the terrain 3D instead of an image, dual cameras is probably the better way to go.
I'm really new with Unity. I just started out using it and I'm not very sure with all the scripting and stuff.
Anyway, the $$anonymous$$imap was done by creating a cube, resizing it and pasting a top view screenshot of my actual terrain onto the cube. I have 2 cameras actually. 1 above the player's head and another shooting down from the top onto the $$anonymous$$imap.
But how can i start scripting? I'm not very sure what to start with. Do you $$anonymous$$d scripting out alittle so i can understand it better and carry on from there? Really thanks for replying. (:
Answer by Peter G · Jun 22, 2010 at 11:56 AM
I'm not sure why you can't use two cameras and place one on top of the terrain. You will use two cameras anyway, one to render the terrain and one for the mini map so you don't gain much benefit from recreating the terrain smaller. But, to make a red indicator, here is what I would do. Create a red sphere and turn lighting off. Now here's where the two possible camera methods that I talked about at the top come in.
If you attempt to do it your way, you may want to try using Renderer.bounds to get the boundaries of the terrain then set up a simple proportion.
playerDistanceFromBoundary indicatorDistanceFromBoundary /*unknown*/
------------------ = --------------------------
distanceAcrossTerrain distanceAcrossMiniMap
Then you could use that to find the x and y coordinates on the mini map. The simplified equation is playerDistanceFromBoundary / distanceAcrossTerrain * distanceAcrossMiniMap. After that, set the player's position to match, and you can do the same with the z if you need to.
var terrain : Transform; //Drag your terrain here in the inpsector var miniMap : Transform; //"" "" minimap here var redDot : Transform; //The red icon;
private var terrainWidth : float; private var terrainHeight : float; private var miniWidth : float; private var miniHeight : float;
private var scaleX : float; private var scaleZ : float;
private var offset : Vector3;
//private var cachedOffset : float; //private var cachedMapPos : Vector3;
function Start () {
terrainWidth = terrain.collider.bounds.size.x; //not needed but adds to clarity
terrainHeight = terrain.collider.bounds.size.z; //same
miniWidth = miniMap.renderer.bounds.size.x; //see above
miniHeight = miniMap.renderer.bounds.size.z;
scaleX = miniWidth / terrainWidth; //find how much we need to scale the ball
scaleZ = miniHeight / terrainHeight; // position
//cachedOffset = miniMap.renderer.bounds.extents.y + redDot.renderer.bounds.extents.y;
//cachedMapPos = Vector3(0, miniMap.renderer.bounds.extents.y, 0) + miniMap.renderer.bounds.min;
}
function Update () { offset = transform.position - terrain.position; offset.y = miniMap.renderer.bounds.extents.y + redDot.renderer.bounds.extents.y; //place the ball right ontop of the miniMap. If you can cache this, delete this // and uncomment the line in start and the variable. //offset.y = cachedOffset
offset.x *= scaleX; //scale the ball position
offset.z *= scaleZ; //scale the ball position
redDot.position = offset + Vector3(0, miniMap.renderer.bounds.extents.y, 0) + miniMap.renderer.bounds.min;
//chache Vector3(0, miniMap.renderer.bounds.extents.y, 0) + miniMap.renderer.bounds.min if the map never moves.
//redDot.position = offset + cachedMapPos;
}
This should work pretty well. It aligns the the red dot with the mini map proportionately with the player's position on the terrain. It also works with non square terrains. As you can see from the above. If you find any typos or bugs. Just post a comment, and I'll see what I'll correct them here.
The other way, the way where you have one terrain and two cameras looking at it, one from the player and one from above saves you all the scaling. You add a red sphere to the players's children directly on top of him (You could use a plane with a texture too). You turn off the lighting and such. Then put the player in a layer called Cam1Only and the ball in a layer called Cam2Only. On the player camera, turn the culling settings so that cam2Only is off, and in the mini map, turn it so cam1Only is turned off. Then, given that the ball is a child of the player, it will follow him everywhere and only it will show up on the mini map, while only the player will show up in the actual game.
the reason is clear. less process wasting and no extra rendering.
I was asked not to use the normal way of doing a $$anonymous$$imap because the terrain I'll be using next time might be very big and might slow down the performance etc. Thats what my $$anonymous$$cher said. So he suggested what I've written above. Therefore I created a cube and scaled it and pasted a screenshot of the terrain onto it.
I did the sphere indicator but I'm confused about the 1st method you suggested. $$anonymous$$ind scripting alittle of the script you've suggested here? So i can start and continue from there. Cause I'm really new to Unity and don't know anything about scripting. ): Thanks for the replies.
Oh, I get your performance issue now. I did not realize that your $$anonymous$$imap is a screen shot. I thought that you had simply scaled your terrain, which obviously wouldn't makes sense. I'll post some code to see if I can help.
Encounted 1 error.
$$anonymous$$issingComponentException: There is no 'Renderer' attached to the "Terrain" game object, but a script is trying to access it. You probably need to add a Renderer to the game object "Terrain". Or your script needs to check if the component is attached before using it.
Indicator.Start () (at Assets\Indicator.js:17)
When i clicked it, it brought me to
terrainWidth = terrain.renderer.bounds.size.x; terrainHeight = terrain.renderer.bounds.size.z;
How do i add the renderer to the Terrain? Thanks for the replies! Really appreciate every single thing. (:
I edited the script. It should all work now. You can save a little performance if you cache the variables that are recommended, but you can only do that if the $$anonymous$$i map doesn't move, which I didn't think it would, but I'm trying to give you a general script.
Answer by Oxy · Jul 14, 2010 at 03:43 PM
It was a very nice idea! ....can you tell me where is the red and gold colors...? I look forward your answer. thank you!
Answer by AnaRhisT · Jun 22, 2010 at 08:53 AM
This will give u a start : http://unity3d.com/support/documentation/Components/class-RenderTexture.html
Answer by Pirate___man · Jun 22, 2010 at 03:15 PM
The way I solved this issue was just to put another camera ontop of your level, and then creat a shape (Box, Uvvsphere, ect.) and put it directly over the players head, high enough so the player cannot see it and low enough so that it is under your second camera. Then make the cube/Sphere/whatever-shape-you-made the child of your player so that it follows the player. I know alot of you probably think this is cheating because of its simplicity but if it works and if it saves time than I say use it. Hope this helps!!
I said the same answer above yours. It's good to see new members inputing their ideas, but if it is the same as someone else's, please just leave a comment.