Jump to content
  • Advertisement
Sign in to follow this  
lampshade

Display a Player Indicator with GUI

This topic is 2954 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Question: How can I make an accurate GUI that displays a player indicator in correspondence to my actual terrain?

Attempted Solution: What I have done is taken a screenshot of the actual map, placed it on a plain (primitivate geometric object) and used a seperate camera in the game scene that has a top-down view of this plain.

The camera can only accept normalized viewing port rectangular coordinates so I can get the map to show up where I want it on the screen. But, it is a viewing port and I won't be able to display anything 'abstract'. But their is a way around this potential solution:

For example, if we have the function in C# syntax:

GUI.DrawTexture(new Rect(920, 340, 400, 325), MiniMapTexture);

This function draws the screenshot of the actual map (abstract) that I was talking about perfectly, at the point on the screen that I want it at, similar to what the camera does (only this works a lot better b/c it only draws the texture).

The code below draws a player indicator and it works beautifully, however, I need it to work for a GUI instead. I would find it a lot easier having it work for a GUI, rather than adding 2, 3 or even 4 camera's in addition to my secondary camera (that takes a top down view of the minimap screenshot) to display all of the abstract plain.


public Transform MyTerrain, MiniMap, PlayerDot;
public Texture2D miniMapTexture, playerIndicator;
private float TerrainWidth, TerrainHeight, MiniHeight, MiniWidth,ScaleX, ScaleZ;
private Vector3 Offset;

void Start ()
{
TerrainWidth = MyTerrain.collider.bounds.size.x; // get our actual x
TerrainHeight = MyTerrain.collider.bounds.size.z; // get our actual z
MiniWidth = MiniMap.renderer.bounds.size.x; // get our mini-x
MiniHeight = MiniMap.renderer.bounds.size.z; // get our mini-z

// Get a "Mini" Version of our actual terrain
ScaleX = MiniWidth / TerrainWidth;
ScaleZ = MiniHeight / TerrainHeight
}

void Update ()
{
Offset = PlayerMoveScript.myPosition - MyTerrain.transform.position;
Offset.y = MiniMap.renderer.bounds.extents.y + PlayerDot.renderer.bounds.extents.y;

Offset.x *= ScaleX ;
Offset.z *= ScaleZ ;

PlayerDot.position = Offset + new Vector3(0, MiniMap.renderer.bounds.extents.y, 0) + MiniMap.renderer.bounds.min;
}

void OnGUI()
{
// Draw our MiniMap Texture
GUI.DrawTexture (new Rect(920, 340, 400, 325), miniMapTexture);

//Don't draw anything outside of this group function
GUI.BeginGroup(new Rect(920, 340, 400, 325));

// Draw our player indicator within the boundaries of the minimap texture.
GUI.DrawTexture(new Rect(Offset.x, Offset.z, 20, 20), playerIndicator);
GUI.EndGroup();
}


The player indicator that the GUI draws it not accuruate in correspondence to the terrain. My Question is how do I draw an accurate player indicator through a GUI function?

Share this post


Link to post
Share on other sites
Advertisement
I am not sure I understand completely what you want, but let me throw some ideas out for you....


For a map, you shouldn't be using a Camera or separate viewport at all. Usually a rendered top down view (or modified version) is best. Let's say your map is 512x512, you will only draw maybe 100x100 area and use UV offsets/texture matrix to translate the image across the 100x100 to look like it's scrolling with you. You'll need to get the dimensions of the world in real units and map them on to the texture size so you can do this properly.

It looks like you're using C#, I don't know enough about those libraries to give you code snippets, but search for texture transform and start there.

Jeff.

Share this post


Link to post
Share on other sites
I did away with the whole secondary camera idea and decided on a new approach yesterday. Since I need to draw a complex 2D shape (not a primitive) for my minimap, I decided to use the GUI.DrawTexture method, which draws the texture as it is, given position on the screen (x, y) and width and length.

So now, with the map drawn, it is a matter of using a Vector2 position varaible to do what I need for when the player moves around in world space.

if (PlayerMovesForward > 0) // incrememnt Vector2 pos.y varaible
else // decrement Vector2 pos.y varaible

Rotating the player indicator is a bit difficult. My current technique for rotating the player is:

float MoveRotate = Input.GetAxis("Horizontal") * RotateSpeed * Time.deltaTime;

which returns a scalar value. I need to be able to get my hands on some tastey degrees and handle each degree (from 0 to 360 either way) so that I can set the direction of the player indicator texture.

I've already went into photoshop and specified a 22.5 degree angle measurement for each of my player indicators --4 for each quandrant.

If I could get degrees, it would then be a matter of reppition to find out which player indicator texture to load.


Edit:---Thought i'd share some code, before I crash for tonight:


private Vector2 pos;

void Start ()
{
pos.x = 1060;
pos.y = 470;
}

void Update ()
{
DisplayWhichArrow();
}

void OnGUI()
{
// Display our Abstract Texture -- "MiniMap"
GUI.DrawTexture(new Rect(845, 290, 380, 320), MapTexture);

// Draw A Game Object
GUI.DrawTexture(new Rect(1060, 424.5f, 22, 22), someGameObject);

// Draw Player Indicator
GUI.DrawTexture(new Rect(pos.x, pos.y, 13.5f, 13.5f), PlayerArrow);
}

private void DisplayWhichArrow()
{
// Forward Indicator movements
if (PlayerMoveScript.MoveForward > 0) // Moving Backwards
{
PlayerArrow = PlayerArrow_DOWN;

if (PlayerMoveScript.MoveRotate < 0) pos.x -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
else pos.x += Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;

pos.y += Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;


}
else if (PlayerMoveScript.MoveForward < 0) //Moving Forwards.
{
PlayerArrow = PlayerArrow_UP;

if (PlayerMoveScript.MoveRotate > 0) pos.x += Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
else pos.x -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;

pos.y -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
}

// Rotating Indicator movements
if (PlayerMoveScript.MoveRotate > 0)
{
PlayerArrow = PlayerArrow_RIGHT;

if (PlayerMoveScript.MoveForward < 0) pos.y -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
else pos.y += Mathf.Abs(PlayerMoveScript.MoveRotate) / 5.3f;

//pos.x += Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
}
else if (PlayerMoveScript.MoveRotate < 0)
{
PlayerArrow = PlayerArrow_LEFT;

if (PlayerMoveScript.MoveForward > 0) pos.y += Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
else pos.y -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;

pos.x -= Mathf.Abs(PlayerMoveScript.MoveForward) / 5.3f;
}
}


It doesn't quite fully work, but you should get the idea.

[Edited by - lampshade on August 25, 2010 1:26:31 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!