- Home /
Health Bar at Player Transform
I know very little about Unity 5 UI systems, but I've spend a frustrating couple of hours sorting through answers and the manual on the topic. What I'm trying to do is create a radial UI bar using an Image UI with a circular fill, and have it follow the player transform at his feet. There are a TON of questions on this topic, going all the way back to Unity 3 & 4 GUI systems - but they all have different solutions and tips, and none of them seem to get me anywhere.
I'm at the point that I have a UI canvas (not a child of any object) and can instantiate a prefab UI image. I've tried making that instantiated object a child of the player transform, but the UI image just ends up in the middle of nowhere with very random behavior.
Seems like the most widely-accepted answer is to set the RectTransform.anchorPosition to the transform.position in screen space during Update() or OnGUI() - but again the UI image ends up in some random place unrelated to that player transform. A side not (but maybe important?) - that UI image that's instantiated isn't even visible in the game view (the actual image texture, that is), I can only find it in the scene view by focusing on its transform.
I'm totally lost - what steps should I take to set up this system? Am I on the right track?
Are you using a Screen Space Canvas or a World Space Canvas? also are you ensuring when you instantiate the UI Image it is a child of a UI Canvas? All UI elements must be a child of a Canvas or they will not render.
I've tried both canvas modes, and I've only achieved random results so far with either. How performance-expensive are canvases? Do I need a canvas as a child for every enemy unit?
I can't say for certain haven't really checked on the impact of many canvases, but you should be fine for using a canvas for each unit (assu$$anonymous$$g there's not hundreds or thousands). If performance does become an issue you could start using a pool of health prefabs and just attach them to units as needed rather then giving every unit in your scene a health bar.
Answer by jinincarnate · Nov 06, 2015 at 02:28 PM
U just need to watch the Tanks tutorial (they have actually added radial health bar under the tank). link text
I'm watching the video now, it's just a bit of a long one. The code that's posted to it is almost identical to what I've been using - at least the portion that moves the image transform. So I need to find how they're setting up their canvas, or what they're doing differently that they're getting different results. Thanks for this!
Got it - I did end up using a canvas child for each unit, with a slider and image as children of that canvas. This video linked by jinincarnate explains in a ton of detail all the steps you need to achieve this. I'm still just prototyping, but playing around with about 5 units on screen at the moment makes no difference (performance-wise) needing a canvas for each unit. Thanks for the help!
Answer by basil4j · Nov 06, 2015 at 08:13 AM
Doesn't answer your question, but an alternative would be to use a textured quad under the players feet and animate the texture.
Thanks for the answer - if I give up on the new ui element I'll give this a shot!
Answer by screenname_taken · Nov 06, 2015 at 12:22 PM
Have you tried making an object with the canvas set at world coordinates and then just parent that to the object that needs the health? Once you parent it, just set it's transform to 0,0,0 and it should go to the pivot point of that object. And since it's parented to it you don't need to have it follow the object through update.
How performance expensive are canvases? I'd have to add a canvas as a child of every enemy unit using this method. I don't expect there to ever be a ton of units onscreen at any time - maybe ~20 tops. Is this practical?
mmmmmniieeeeeeee.....go with a quad under the feet of the unit and use an unlit shader. It's what i did for a countdown timer thing on my game that used a textured disc, slowly fading out.
Answer by AngryTilde · Nov 06, 2015 at 03:46 PM
What you could do (assuming you want to instantiate a Health Radial separate from your characters) would be to create a prefab containing a UI WorldSpace canvas with your graphic as a child. Then to create a script on your character GameObject with something like the following:
public GameObject m_HealthCanvasPrefab;
void Start () {
GameObject healthRadial = Instantiate(m_HealthCanvasPrefab);
healthRadial.transform.SetParent(transform, false);
}
That snippet would instantiate the prefab and child the prefab to the object at 'start' and as we are using the SetParent overload it will keep its original local position.
I haven't tried parenting the actual canvas, but I have tried parenting the image or slider (the child in your case). This method means I'll need a canvas for ever unit - I was skeptical to do this because I assumed canvases were pretty expensive on performance. Someone above posted a similar answer, stating that a number of canvases shouldn't be an issue. I'm looking into this now, so I'll report back!
That's explains the behavior then without a parent canvas the ui element won't render, but this would only work if the root (parent you are attaching to) didn't rotate, otherwise it might look a bit weird... that Tanks tutorial video has a much better solution for your case I think.
Thanks a bunch for the help - I finished that video and it had a very detailed explanation of how to do this by childing the canvas to the gameobject as you suggested. Thanks!