Player Name Overlay
Tuesday, January 9, 2018I'm prototyping shit at the moment, and since I'm wanting to blog more this year I figure I'd post some tutorials if I do anything that seems useful. Fair warning, I'm trying to get out of the habit of trying to write clever reusable code. I feel like it's a trap I fall into a lot, and it's more important to get shit done and realise that you'd never want to reuse that code anyway. Today I'm gonna show how to easily position player names on a 2D canvas in Unity UI. It looks like this, and can obviously be things like health bars and stuff too.
List Of ObjectsYou need a list of objects that want to show text. You can do this however you want. My list is a list of players, so I'm going to stick a static list on my player class. Then add/remove from the just in OnEnable/OnDisable. Now our list of players are available in Player.All.
Canvas LayoutSo, do this:
- Create a Canvas (GameObject > UI > Canvas)
- Add a new Panel, name it PlayerNames (Right click Canvas, UI > Panel )
- Make the panel full screen (Click, shift click and alt click on this button)
- Change the pivot on the PlayerNames panel to be 0 and 0 (will explain this later)
- Add a child Text to the panel, called Name.
CodingSo all we need to do now is create a script on PlayerNames. I called it PlayerNames. So first of all we need an array to store all our "Name"s. Then in Start, we'll copy the Name text component. Note that here we've copied the Text game object 9 times. We do this because we don't want to be creating and destroying them every frame (because Unity hates that shit). So in our Update function, lets do this. We get the list of players, ordered by the distance from the camera, closest first. I've commented the rest inline, it's pretty self explanatory.
Pivot PointSo as mentioned in the comments, the localPosition of our child RectTransforms are relative to the pivot position of the parent. The long and short of that is that if the pivot position is 0, 0 then we're just doing the pixel position from the top left. If the pivot point is 0.5, 0.5, then you're doing the pixel position from the center of the parent panel (in this case, the same size as the screen). You don't particularly need to know that shit, it's just useful to know when trying to get rectTransforms to do what you want.
ShakesIf you've got a critical eye, you might notice that it's got the very slight shakes. https://files.facepunch.com/garry/2018/01/09/%202018-01-09%2022-32-51-710.mp4 Rounding down helps https://files.facepunch.com/garry/2018/01/09/%202018-01-09%2022-36-58-864.mp4 But there's still something weird.
Script OrderWhat you're seeing is a common thing with using the Update function. The problem is that our Update function is running before the Camera moves. So we're a frame behind every time. So open Edit > Project Settings > Script Execution Order Then add your script under the Default Time. This means that this script's Update will be called after every other Update in the project. If your text is still kind of wobbly, you might need to think more about your script order.
SummarySo there you go. Health bars are kind of just as easy, just replace the Text component with a custom component (although using Unity's built in UI > Slider component works easily enough). There are a few more math challenges if you're scaling your canvas, but it should just be multiplication. Something to note also is that this will show player names even if you can't see them, like if they're the other side of a wall. you'll probably want to do a ray test or something from the camera to the world point where the player name is going to be if that's a problem.
Turn your phone to view blog list