How to make labels not be affected by the camera?

Hello! I have a scene with a label, camera and a node with lots of 3d sprites. How can I move the camera around without affecting the position of the label. The label is supposed to be a part of the GUI overlay. The project is c++.

You can move the root node, where you attach all labels, by the same amount as the camera. Also offset by the inverse scale if you’re zooming in/out the camera.

You could instead attach all game nodes to a root node and move it in the opposite direction that you would move a “camera” as a way of sort of having a virtual camera.

Another option is attach your HUD labels and other nodes that you don’t want to move with the camera to a 2nd camera. For example, you could use the DEFAULT camera for our HUD since it renders last, but you can use one of the DEFAULT, USER1 through USER4 cameras. You’ll have to mask all of your nodes if you do it this way.

Thank you so much! I will try moving the hud to the opposite direction. I just came from Cocos3D to Cocos2D-X and some things are a bit hard like the coexistence of 2d and 3d because in Cocos3D you had separate classes for 3d scene and 2d layer. Maybe it’s possible in Cocos2D-X too?

Honestly if you’re mixing a 2d hud with 3d world I would look into using a 2nd camera.

Translating the hud if your 3d world camera can rotate at all would be annoying, though obviously still possible. I think the demo game FantasyWarrior3D (or something like that) shows how this works (though it’s written in Lua). There’s also probably some useful insight on the programming guide and in the cpp-tests project.

Ok, cheers! I’ll look in to the 2nd camera option. If it works i’ll post the source code.

This is the code I got it working with. Now manipulating the camera3D doesn’t affect the labels at all, just the 3D box.

Thanks again Steve!

auto wsize = Director::getInstance()->getWinSize();

auto camera3D = Camera::createPerspective(5, (GLfloat)wsize.width/wsize.height, 1, 3000);

camera3D->setPosition3D(Vec3(0,1500,1500));
camera3D->lookAt(Vec3(0,0,0), Vec3(0,1,0));
camera3D->setCameraFlag(CameraFlag::USER1);

addChild(camera3D);

auto camera2D = Camera::createPerspective(30, (GLfloat)wsize.width/wsize.height, 1, 2000);

camera2D->setPosition3D(Vec3(0,0,1500));
camera2D->lookAt(Vec3(0,0,0), Vec3(0,1,0));
camera2D->setCameraFlag(CameraFlag::USER2);

addChild(camera2D);

auto topLabel = Label::createWithTTF(“TOP LABEL”, “fonts/arial.ttf”, 20);

topLabel->setPosition(Vec2(0,(wsize.height)*1.15));
topLabel->setCameraMask((unsigned short)CameraFlag::USER2);

addChild(topLabel);

auto bottomLabel = Label::createWithTTF(“BOTTOM LABEL”, “fonts/arial.ttf”, 20);

bottomLabel->setPosition(Vec2(0,-(wsize.height)*1.15));
bottomLabel->setCameraMask((unsigned short)CameraFlag::USER2);

addChild(bottomLabel);

auto world = Node::create();

auto sprite = Sprite3D::create(“box.c3t”);

sprite->setPosition3D(Vec3(0,0,0));
sprite->setCameraMask((unsigned short)CameraFlag::USER1);

world->addChild(sprite);

addChild(world);

1 Like

That is nice for a few labels but what if I have a sprite with children and grand children that may get added and removed dynamicallty. Suddenly I have to worry about applying a camera mask to all these sprites coming and going. It would be nice if anything on a layer could automatically be assigned to a specific camera. Moving layers still makes more sense to me at this point for 2D. Clearly though cocos2d is focused on 3D now but if I wanted a 3D engine I would have just used Unity from the beginning.