# libgdx - Scalable UI without Scene2D

I currently have a fairly decent framework for a side-view strategy-ish game built around libgdx. While I may have reinvented the wheel a couple of times, I believe I've done the vast majority with tools already existing in libgdx parts properly: camera, viewport, sprites, etc.

One thing I've not used at all is Scene2D, as I've simply not had a need for it (yet). Drawing the sprites at their positions is more than enough. The terrain is procedurally generated pixel art that is drawn beforehand.

Now I've come to the point where I need to implement some fairly basic UI-systems. Nothing out of the ordinary: A few buttons to click, and an area with additional info.

I haven't decided entirely on which approach to use when implementing the UI, but in the meantime I'm going with a fairly simple approach: When everything else is drawn, I reset the projectionmatrix so that everything drawn after that never moves with the world:

    Matrix4 uiMatrix = camera.combined.cpy();
uiMatrix.setToOrtho2D(0,0,viewport.getWorldWidth(), viewport.getWorldHeight());
batch.setProjectionMatrix(uiMatrix);
// Then draw the UI


This works fine, except when the aspect ratio changes and/or when the window resizes. Therefore I would like to find a more scalable way.

Is Scene2D the way to go? It currently looks like the only reasonable way of getting an UI that works well with resizing the screen and panning around.

The info I find on how to implement it either assumes a complete rewrite to use actors instead of sprites, or doesn't scale well at all.

Take a look at Viewports. In short, Viewports are handy little objects that handle the matrices for your player's view. Though they are integrated into Scene2D, you don't have to use Scene2D to use them. Before any render calls, just call

myViewport.apply();


Most Viewports take a Camera object in their constructor which you can use to easily pan the screen.

I do want to note however, that I love Scene2D and using it gives you a lot of helpful features. You may want to look into using Scene2D just for your UI layer.

You'll most likely need to use multiple viewports and cameras for your UI and game. Here's how you would do that

//Create the separate viewports and cameras
OrthographicCamera gameCamera = new OrthographicCamera();
FitViewport gameViewport = new FitViewport(800,600,gameCamera);

OrthographicCamera uiCamera = new OrthographicCamera();
FitViewport uiViewport = new FitViewport(800,600,uiCamera);


gameViewport.apply();
//render game
uiViewport.apply();
//render ui


To handle screen resizing, you need to tell your viewports about the new screen size whenever it is resized

public void resize(int width, int height) {
gameViewport.update(width, height);
uiViewport.update(width, height);
}

• I use a Viewport for everything else, as it allows me to keep aspect the ratio regardless of resizing. The reason why I'm not using it for the ui as well is because the camera can pan and zoow, and I want the ui to remain static. I have considered using a separate camera and viewport for the ui (if possible), but I'm unsure as to how I'd implement this alongside the existing one. – Jarmund Aug 22 '16 at 21:20
• I must have misunderstood then. What problem were you having with window resizing then? It is possible to use multiple viewports/cameras. I will update my answer with how. – spectacularbob Aug 22 '16 at 21:30
• The problem is that I haven't found a clean-looking way that both allows for resizing and allows for proper coordinate-translation (world vs screen vs input). Multiple cameras and/or viewports should solve this, as code not ui-related works fine (clicking on units, placing entities, etc). Code example would be much appreciated. – Jarmund Aug 22 '16 at 21:44