Controlling Hierarchy of Billboard Effects

So I am currently implementing health bars above units in my RTS trial. I do this by placing a “total health bar” graphic, using an OnscreenImage with .setBillboardPointEye() above the units, and then by reparenting a slightly smaller, brighter “current health bar” to the total health bar (I do it separately because I want to be able to modify the size of the current, but not the total, bar when the unit takes damage).

However, I find that all I see is the parent bar; I can only see the smaller, brighter bar if I make it bigger than its parent. I want to be able to see the current health bar in front of the total health bar, but it seems to be behind it.

I can correct this by parenting the total health bar to the current health bar instead, but I suspect this will lead to problems, or at least complications, when I have to resize the current health bar without resizing the total health bar. I’ve tried changing the Y on the billboard effects, to no avail. Is there a simpler way to put the child billboard in front of the parent billboard?

Why not try using a common node: parent all of your geometry to one ordinary PandaNode, and set the billboard effect on that node. Then you can position and scale the relative nodes without impacting each other.

David

Okay, so I tried using a common node, but depending on how I rotate the camera, one billboard or the other appeared in front, rather than it always being the one I wanted. Of course, this makes sense, since they are both at exactly the same spot in XYZ space, so they would randomly jitter back and forth - but I want one to always be a little bit closer to the camera, regardless of how the camera is rotated.

However, I do have a solution, in case anyone else has a similar issue. I almost had it before, too - I had just been neglecting to put Y changes in the negative. What I did to make the current bar appear in front of the total bar was reparent it to the total bar, and set its position to (0, -0.01, 0), in other words very, very slightly in front of the parent bar.

This feels a bit like cheating, but it gets the job done, and I can’t really tell that the two aren’t exactly on top of each other (using a bigger value, like -1 or even -0.1, has the smaller bar constantly appearing to change position as the camera rotates).

Using the above technique when both are parented to a third node results in the total health bar always appearing in front and obscuring the other bar. At the moment, then, my working code looks rather like this:

        self.HPNode = self.actor.attachNewNode("HPNode")
        self.HPNode.setBillboardPointEye()
        self.HPNode.setLightOff()
        self.HPNode.setTransparency(TransparencyAttrib.MAlpha)
        self.HPNode.hide()
        
        self.totalHealthBar = OnscreenImage("HPTotal.png")
        self.totalHealthBar.setScale(3.5, 1, 0.6)
        self.totalHealthBar.reparentTo(self.HPNode)
        self.totalHealthBar.setPos(0, 0, 6)

        self.currentHealthBar = OnscreenImage("HPCurrent.png")
        self.currentHealthBar.setScale(0.9, 1, 0.7)
        self.currentHealthBar.reparentTo(self.totalHealthBar)
        self.currentHealthBar.setPos(0, -0.01, 0)

The whole HPNode doesn’t seem necessary, it’s rather a leftover from trying to get both to work under a single parent node.