UI sure is cool, right fellas? There is just one pet peeve of mine; it doesn’t update in the scene view.
Now, my health bar itself is nothing much special to look at, other than that I use a slider instead of an image (it just seems more practical). But what I DID spent much effort on was finding out all kinds of tricks to make it update in edit mode, and this is the result!
(This wasn’t easy guys, I’m cool.)
There were 2 things I needed to do to accomplish this, and both were a pain in the butt.
In order to update the color of the health bar I made use of getters and setters. The way I do it only works because I use a slider, which I won’t go into now (remove the handle, set background to red and the fill to green and I’m sure you’ll figure it out). Anyway, here is a slimmed down version of what I do:
[SerializeField] private float _health = 100;
[SerializeField] private Slider healthSlider = null;
public float Health
{
set {
// MathfEx.Map maps the health to a value the slider can understand - look up the forum post below to learn what Map does!
healthSlider.value = MathfEx.Map(_health, 0, _maxHealth, healthSlider.minValue, healthSlider.maxValue, true);
}
}
void OnValidate()
{
// Applies getter and setter logic on inspector changes.
Health = _health;
}
By the by there are a lot of problems with using getters and setters so I can’t actually recommend you use them (though I AM working on something that should fix all of their bugs).
Right, so that makes it so that health UI updates together with Inspector changes. I HIGHLY recommend you make the player and enemy UI part of the player and enemy, so that way you can link their slider up in your prefabs as well (prefabs can’t accept scene instances).
But of course, Ben had to ruin my day and introduce a new issue: facing the camera.
This one didn’t take as long because I was lucky enough to find someone who had already solved this problem, and following the programmer oath I always try to steal as much code as I can.
Here’s the gist of it:
[ExecuteAlways]
public class FaceCamera : MonoBehaviour
{
private void OnRenderObject()
{
if (Application.isPlaying || !Camera.current) return;
transform.LookAt(Camera.current.transform);
transform.rotation = Quaternion.LookRotation(Camera.current.transform.forward);
}
}
I’ll break it down for you. [ExecuteAlways] will make your monobehaviour execute… always. No matter if you’re in game view, scene view, or the newly added prefab mode, your script will run your code! (Though with some odd differences like Update only being called once in the scene view.)
OnRenderObject() is called on every repaint of the scene- or game view. I first make sure the game isn’t playing (we use Update() in playmode) and this one guy in this one forum said you had to check if Camera.current wasn’t null or things could break, so I thought to myself: “Why not?” The rest is just Bens code but using Camera.current (which corresponds to the view or mode you are currently in).
If you wanna learn more about ExecuteAlways go here!
And that’s the steps I took to make my scene resemble my game view! I care deeply for this kind of stuff, as I think not only can it prevent misconceptions about how objects react to changes in your game, it also brightens up your workspace and makes editing that much more fun! Like modelling in 3D, which is cool, but it can quickly become boring to edit a white hunk of clay if you don’t give it some distinctive colors.
Cheerio, hope this amazes someone!