RTS-Camera (WASD move, EQ rotate, mousewheel zoom, edge scroll)

Hello there!

TLDR:
Playground for RTS-Camera: https://playground.babylonjs.com/#8SZ28Q#6
Controls:

  • WASD/ArrowKeys - movement
  • mouse near edges - movement
  • E,Q - rotation
  • mousewheel - zoom in/out

Notes:

  • Edge navigation is controllable by ‘_alphaEdgeScroll’ (Line 117)
  • Edge navigation can be disabled by ‘_enabled’ (Line 108)
  • Camera speed is camera.speed (Line 53)
  • Rotation speed is part of camera.metadata (Line 67)
  • Zoom speed is part of camera.metadata (Line 81)
  • Boundaries (zoom, movement) is part of metadata (Line 69-72, 78-79)
  • All three camera inputs (mouse on edge movement, zoom by mouse wheel, keyboard movement) are independent from eachother

Background
My game needed a rts-camera, but unfortunately i couldn’t find any in babylon. ArcRotateCamera was perfect rotation-/zoom-wise, UniversalCamera was perfect for movement. But i couldn’t find any camera with movement, rotation and zoom in combination with moving the camera by moving the mouse next to the edges in documentation nor playgrounds.
The last few days were very interesting (try and error with different techniques), full of joy and frustration. You can find the result in the playground.
A universal camera is used as camera. There are three camera inputs:

  • mouse input, which generates the edge areas (gui) and moves the camera in that direction, if the mouse moves over those gui elements
  • keyboard input, to move and rotate the camera with keys
  • mouse wheel input, to zoom in and out by modifying the fov

I couldn’t find a way for overlapping gui elements firing their events. Only the events of the visible gui element is fired. Therefor there are 8 edge areas (4 edges, 4 corner).

Have fun :slight_smile:

Edit: Updated playground - Bugfix for shaking camera, when zoomed in/out

5 Likes

This looks really cool @Pandadoxon !

Thank you very much for the amazing example!

Hello and welcome to BJS,
First, let me tell you that for a first contribution to the forum, this is really a nice effort and something that can be useful to the community.
Next, may be you noticed that at full zoom level the camera seems to have some collision issue causing the scene objects to ‘shake’? Also, (in my opinion) the edge movement has a bit too much ‘inertia’ in it (understand, not reactive enough).

Last, for

I can help you with this one. For the GUI, you will want to use a second camera, have your GUI on a higher level of layerMask and attach both scene and GUI cameras at once.

Thanks for the feedback @mawa . The shaking was caused by not hitting a condition. Therefor the diff was always too high or low to stop zooming.I fixed it and edited the link in the initial post.
For the edge movement: It’s the same speed as the movement with keys. Whoever wants to use this camera settings can adress the inertia by changing camera speed or the lerp factor (Line 332 for mouse, Line 505 for keys).

For the gui i prepared another playground: Babylon.js Playground
My hope/expectation was, that when i move the mouse above the blue gui element, it triggers both, rect1 and rect2. But only rect2 is displayed in console. I couldn’t find a way to bubble the event mouseover for both gui elements.

Yes, well. You should not expect to overlap/layer your GUI to trigger a function. That’s just too messy. Instead, rectangle 2 (which I assume to be the corners/diagonals of your window) would trigger 2 functions (1 for the horizontal move and 1 for the vertical move). There’s actually another problem I detected as of right now (from your first PG). When you quickly move out of the canvas/window, the move is not detected and not kept (or aborted). I also think the code starts to look quite long and complex. I believe there must be a more ‘straight forward’ approach to this, but on the other hand, I have to admit I never did something like this before. May be the input from some other people at this point would be good @Evgeni_Popov Any suggestions towards this attempt?