top of page
Search

Log 25: Maps Are Great for Directions!

  • Writer: Kassandra McCormack
    Kassandra McCormack
  • Jan 11
  • 5 min read

What I really wanted to work on was quests and mission objectives. But, realized it would be helpful to develop a mini-map system to display those objectives first, that way players could know about them and I could know how the objective system needs to be structured to be displayed. I also thought it would be easier to do, because surely there must be a plethora of good mini-map tutorials, it is such a common game feature! And I did find several of them, unfortunately I wound up having to Frankenstein them together and even had to figure out some of the math on my own in order to get a system I was happy with.


Warriors games have two mini-map states (in addition to a third, larger map on the pause screen but I'm not there yet): a full map view and a zoomed in map view. The full map view shows a simplified, top-down view of the full level map, useful for seeing where the player is in a level and how to navigate it quickly as well as important enemies or objectives. The zoomed in map is mostly useful for parsing dense throngs of enemies and seeing exact placement of all characters around the player.


The first thing I did was make a new widget that just contained a Widget Switcher so that I would be able to do a simple button press and swap between map views. Eventually I will wind up doing away with this, but not for a while.


I started with the zoomed in map as most tutorials are for that. Following those tutorials I created a material that tracks the player over a map texture. That texture was made by me by taking an overhead snapshot of the level and modifying it in GIMP. However, unlike the tutorial, my map showed my character in a very wrong position.

ree

I wound up having to include seemingly arbitrary offsets to the calculated X and Y coordinates in order to correct the map. Which was frustrating as the math worked perfectly for the person in the video, but I got it to work eventually.


One of the caveats with how the mini-map material is put together is that it relies on a Material Parameter Collection (MPC) for the character's position, making it impossible for couch co-op. Fortunately, I already settled on making this a single-player game so that will be a concern for my next project.


I decided that in addition to displaying an icon to represent the player on the map, I would make one for the camera as well, that way players can see and locate things better and easier. For this I made a new component that updates the rotations of the icons (I don't need to update positions for it because of the way the mini-map works the player is always in the dead center of it). Sadly, it seems the engine doesn't like my component as every time I restart the project I have to delete it and put it back on the player character or the blueprints won't recognize the component references.

ree

The next thing to do was put enemies and generic points of interest (POIs) on the mini-map. For these I made an abstract base component to handle the shared logic and then two child components to handle specific logic for each level of mini-map zoom. As far as tutorials I had to go through several before I landed on one that actually worked for me (thank you ShawnTheBro). However one thing that frustrated me (but makes absolute sense) is that if a widget is not being actively displayed it does not do its Tick event. This posed a problem because I had put the movement code for the POI icons into the individual icon widgets themselves, as well as the check whether they are inside or outside the zoomed-in map's edge to turn off or not. So once they went off the edge of the map and turned their visibility off, they no longer ticked to realize they should show back up again. In order to work around this, I had to create a new array in the mini-map parent widget that manually calls the Tick event on all members of the array.

ree

Next I worked on the full-size mini-map. I managed to find a single tutorial that went over a non-zoomed in map, and when I tried following the math in it I wound up with my player character and enemies were showing up in all kinds of incorrect locations. Eventually I had to redo and solve the equations for myself. One of the things that threw me off was that originally my map UI was stretched to fit inside of a square; I figured out that it actually needs to be at the same relative resolution as the actual map, or the math would not work. Because of this I couldn't have the widget anchors be in a square, nor could I have both of the maps be children of a switcher and instead have to have them as individual widgets that I manually switch between. This will have the unintended upside that while the zoomed-in mini-map can remain a square, if I have a full map that is a long rectangle I can have the whole thing be easily displayed without squishing.


One thing with the full size map that I struggled with for a while was that my math was working perfectly for vertical (on the map) movement, but when I moved horizontally it would line up with the center of the map fine and then go off the sides. I wound up having to add an extra 200 Unreal Engine (UE) Units to the map's Y directional size, and I still don't understand why. But it works so I'm not questioning it anymore.


Unfortunately while I needed the extra 200 UE units to get the full-size map to work, they caused the zoomed-in mini-map to no longer function. So I had to go into both the widget control code for the full size map and the MPC for all these materials and functions and add an extra step to account for the extra units.


The final thing I worked on was getting bases to show up on the two mini-maps and be the correct colors based on who controls them. The major problem is that I want the bases to smoothly move off and on the zoomed-in map and not pop in and out when an arbitrary point passes the cutoff point. In order to do this, I had to make a new material that copied most of the zoomed-in map material code, without the outline around the map. Then, I introduced an additional overlay on the widget to layer a bunch of images, each with this new material loaded with a translucent texture of a single base, over the main map material. Because they use the same MPC for all of them, the materials all line up perfectly. Finally I just had to make the textures white so that the individual bases themselves can determine the color tint of the image widget.


The zoomed-in mini-map got the bases working immediately. The full size map was even easier as it just needed to overlay images without fancy materials onto the map.



 
 
 

Comments


bottom of page