[SOLVED] CocoStudio/C++ ui:widgets setGlobalZOrder doesn't work(BUG v3.6/v3.7)

Hi guys,
I’m having a problem with a scene I’ve created with CocoStudio. On the scene I’ve a background, a top HUD bar(lives,score,etc).
My enemies come from the top of the screen and my problem is that I add the enemies to scene dynamically and when they appear on the screen they come up on top of the top HUD bar, and I want them showing up under the top HUD bar.
I tried addChild(enemies), addChild(enemies,0) and I got same result.

How can I change the top HUD bard Z order in the way it comes on top of everything? I know I can create the scene
programmatically but that is a very slow approach, that’s how I was doing before and CocoStudio made things so easier…

The problem is when I’ve many enemies they cover the score or lives, etc… if they come under the top HUD bar it wouldn’t be a problem.

Thanks in advance for the help…

Cheers,
MadMax

Try calling something like hud->setLocalZOrder(100); This is will make sure your hud is always drawn on top as long as no other node has a z-order higher than 100

Thanks a lot for your help!
hud->setLocalZOrder(100) didn’t do the trick as the sprites aren’t all added through the CocoStudio scene, but hud->setGlobalZOrder(100) did…

I didn’t even know setGlobalZOrder exists :smiley: .

I actually figured out that the setGlobalZOrder of any ui::Widget descendent doesn’t work… It works fine for sprite. If you add any sprite to the CocoStudio scene(.csd/.csb) you set the global Z order and it will accept it. But the same doesn’t apply to ui::Button, ui::Text/Label, ui::ProgressBar etc…
I’m not sure if this is a bug on v3.6 or it’s designed this way. If it’s designed this way I’ll have to throw away all my work, over 20 screens done in CocoStudio and build them programmatically. This is going to be a pain.

I tried to debug the ui::Widgets but I’m couldn’t find the issue… I don’t know if the guys will have time to help me out with this as they are already working on 3.9 and I can’t upgrade to 3.7 or 3.8 right now. I need to finish this game first, it’s already taking a long time to develop it and if I start trying to upgrade to all cocos2d-x versions that come up, I’ll never finish it as there always something that was deprecated or doesn’t work as it used to… etc…

Anyway, I hope to find some help with this without having to go back doing screen manually…

I create a simple test with a sprite and a text.
I set the text label to “ON TOP”. and put the sprite on top of it.
Then on the code I set the text global Z order to 100 and it’s still under the sprite…

On my game as the first picture shows, I’ve a sprite with a score label on top of it, so to make the enemy move under the sprite I set the sprite global Z order to 15 and I do the same for the score label, the enemy goes under the sprite, but also the score label… The score label doesn’t show up as it’s behind the sprite because its global Z order doesn’t nothing.

Can you try adding your hud to the scene like addChild(hud, 100); and add your sprite with this addChild(sprite, 80);

that works only if it the scene is not created using cocos studio, because cocos studio loader add all children to the root node when reading the scene file. Also, I tested creating a ui::Text manually and the z order doesn’t work at all. I’ve opened a bug on cocos2d-x github repo. The same happens on v3.7.
Hopefully someone will pick it up and help me out or this will delay my game release…

I’ve fixed it myself. I had to make changes to ui/widgets:: UILoadingBar,UIText,UIButton ui/base::UIScale9Sprite.

I’ve added the methods setGlobalZOrder and getGlobalZOrder to them and
on setGlobalZOrder I’m setting the global Z order on their respective
renderer.

I’ve also added setBlendFunc to the ui::Button to be able to set blending functions on the buttons…

We also added setPositionZ to many of the widgets, though I feel like they’re slowly getting fixed in master repo. You could open a github issue regarding this.

Our solution was to eventually just add a 2nd camera for the HUD, now we no longer have to worry about the render order Z index (setGlobalZOrder/setLocalZOrder) other than to order the hud widgets between themselves. This does add a little complexity elsewhere though (setting camera masks).

I’ve opened an issue on github and after I found the solution I closed… I’m happy to push the code if you are interested.
I haven’t used cameras yet, I haven’t need it them, but that sounds something to try. I’ll play with setPositionZ too and see if I get the same results, if I do, the changes I made may not be relevant anymore.

No worries, we’ve added our own similar code to our fork of the engine. setPositionZ is mainly for if you use the depth buffer and/or layer sprites using 3D positioning, so you’re probably better off with local/global z.
Cheers

Hi Steve,

I am currently facing the same issue in 3.10, I found your reply set we can add another camera for HUD. Is there any example about this?

Brief info about using camera object: http://cocos2d-x.org/docs/programmers-guide/3d/index.html

Not much of a guide, but there’s a little code on this discussion of a bug with the camera implementation (fixed in 3.9 I believe): [Solved] Label as child doesn’t move when parent position updated with 2 Cameras

Check a few different tests in the cpp-tests project: Camera3DTest, Scene3DTest, Sprite3DTest.

For 2D game a reasonable setup is three cameras: background, game, hud.

It’s also reasonable to use global Z and/or local Z (and possibly the depth buffer) instead.

You’ll also note that it was created mostly for 3D, but can be used as a forceful separation of nodes into “layers”. Also I would mention that you can combine flags/masks so that objects can render during more than one camera’s visit and camera’s can render objects of more than one flag/mask per visit.

Hope that helps.