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 ? :slight_smile:

Thank you so much :smiley:

It is fairly simple fix if you are using GUI.
You have to use GUIUtility.RotateAroundPivotto 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 expensive
  • you might want to consider enemy queue to loop through, enemy would register, add himself to the queue in Awake() and remove from it OnDestroy() then you can just loop through enemies in the queue

Happy coding.