- Home /
Minimap rotation
Hi, i have made (with the help of MakakWasTaken) a minimap, the camera is a child of the player and this is the code i attached to the camera:
public Transform player; public Texture enemyMarker; public Texture marker; List enemyPos = new List();
void OnGUI() {
Handles.DrawCamera (new Rect (5, 5, 105, 105),camera, DrawCameraMode.Normal);
foreach (Vector2 Pos in enemyPos) {
if((Pos.x > 0 && Pos.x < 100) && (Pos.y > 0 && Pos.y < 100))
GUI.DrawTexture(new Rect(5+Pos.x,5+Pos.y,enemyMarker.width,enemyMarker.height), enemyMarker);
}
GUI.DrawTexture(new Rect(55-(marker.width/2),55-(marker.height/2),marker.width,marker.height),marker);
}
void Update() {
enemyPos.Clear(); //This might be .clear instead, I do not remember
foreach (GameObject enemy in GameObject.FindGameObjectsWithTag("Enemy")) {
enemyPos.Add(Vector3ToMap(enemy.transform.position));
}
}
Vector2 Vector3ToMap(Vector3 pos) {
Vector2 ret;
ret.x = pos.x-player.transform.position.x+50;
ret.y = pos.z-player.transform.position.z+50;
return ret;
}
I have a problem, if my player turn and change position the camera (which i use to create the map turn with him) but how can I turn also the textures used to indicate enemy and player ? :)
Thank you so much :D
An easy way to achieve this is to put planes above the players and enemies with the textures that represent them and put them on a layer only the $$anonymous$$i-map will see. So it would be something like this:
Enemy -> Plane with enemy$$anonymous$$arker texture.
Player -> Plane with player$$anonymous$$arker texture.
This way you don't have to loop through the enemies and each enemy or player will automatically keep it all updated.
Answer by IndieForger · May 04, 2015 at 06:00 AM
It is fairly simple fix if you are using GUI. You have to use GUIUtility.RotateAroundPivot
to modify GUI.matrix
(remember to restore it afterwards):
GUIUtility.RotateAroundPivot(player.transform.localEulerAngles.y, playerBlipPosition);
Needed quick warm up before long day of work so here here is full example.
Just copy and paste that script, attach player and adjust zoomDelta
parameter to fit your needs.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GUIMinimapController : MonoBehaviour {
public Color minimapColor = new Color(1, 1, 1, 0.1f);
public Rect minimapRect = new Rect(0, 0, 200, 200);
public Color playerColor = new Color(0.5f, 1f, 0.5f, 1);
public Rect playerMarker = new Rect(0, 0, 4, 4);
public Color enemyColor = new Color(1, 0.5f, 0.5f, 1);
public Rect enemyMarker = new Rect(0, 0, 2, 2);
public Transform player;
[Range(0 ,1)]
public float zoomDelta = 0.4f;
private Vector2 playerBlipPosition { get { return minimapRect.center; } }
List<Vector2> enemyPositions = new List<Vector2>();
GameObject[] enemies;
Texture2D blipTexture;
// Use this for initialization
void Start () {
blipTexture = new Texture2D(1,1);
blipTexture.SetPixel(0, 0, new Color(1,1,1,1));
blipTexture.Apply();
enemies = GameObject.FindGameObjectsWithTag("Enemy");
}
void Update() {
enemyPositions.Clear();
Vector2 enemyPosition;
foreach (GameObject enemy in enemies) {
if (IsVisible(enemy.transform.position)) {
enemyPositions.Add(Vector3ToMap(enemy.transform.position));
}
}
}
bool IsVisible(Vector3 position) {
float maxDist = ((minimapRect.width + minimapRect.height) / 4);
return Vector3.Distance(position, player.transform.position) <= maxDist * zoomDelta;
}
void OnGUI() {
Color color = GUI.color;
Matrix4x4 matrix = GUI.matrix;
// draw minimap
GUI.color = minimapColor;
GUI.DrawTexture(minimapRect, blipTexture);
// draw enemies
GUIUtility.RotateAroundPivot(player.transform.localEulerAngles.y, playerBlipPosition);
GUI.color = enemyColor;
foreach (Vector2 enemyPosition in enemyPositions) {
Rect r = new Rect(enemyPosition.x, enemyPosition.y, enemyMarker.width, enemyMarker.height);
GUI.DrawTexture(r, blipTexture);
}
// restore matrix
GUI.matrix = matrix;
// draw player
GUI.color = playerColor;
Rect playerRect = new Rect(playerBlipPosition.x - playerMarker.width / 2,
playerBlipPosition.y - playerMarker.height / 2,
playerMarker.width,
playerMarker.height);
GUI.DrawTexture(playerRect, blipTexture);
// return color
GUI.color = color;
}
Vector2 Vector3ToMap(Vector3 pos) {
//Debug.Log (pos.x - player.transform.position.x);
Vector2 position = new Vector2(
playerBlipPosition.x + (pos.x - player.transform.position.x) / zoomDelta,
playerBlipPosition.y + (pos.z - player.transform.position.z) / -zoomDelta
);
return position;
}
}
Few notes about the whole approach though:
GUI is not the best option for drawing minimaps, consider ugui to reduce draw calls
if you decide to use UGUI you can rotate your minimap as oppose to translating all the blips
try to avoid using
GameObject.FindGameObjectsWithTag()
in update method, it is expensiveyou might want to consider enemy queue to loop through, enemy would register, add himself to the queue in
Awake()
and remove from itOnDestroy()
then you can just loop through enemies in the queue
Happy coding.
Your answer
Follow this Question
Related Questions
Creating an axes representation on the screen? 0 Answers
Minimap North Direction 1 Answer
Mini-Map skin? 1 Answer
Camera rotation around player while following. 6 Answers
Making a 2d "radar" for space game 2 Answers