FPS Game Shooting Weapon Interface

Well, we need some staging ground to start with. What would you suggest?

I like these two.
.GitHub - squeek502/bunnyhop-webgl: Quake/Half-Life style bunnyhopping in WebGL/BabylonJS

.GitHub - BabylonJSGames/BabylonJS-Platformer-Game-Prototype: A 3d platformer browser game prototype made with the BabylonJS framework written in TypeScript.

I like the platformer because it has both third and first person camera/controls set up. I have a local version that is boiled down to 2 files and all the colysus stuff removed. However, the player controller is coupled to several properties of the game world . For instance, the world has a timer running that the player controller references. Will need some refactoring i think

The first one, bunnyhopping, seems not so good as this - https://playground.babylonjs.com/#4U5T2X#18

The second, platformer, is much better; but it is just platformer, not a FPS in its classic sense. But it is possible to make something cool out of it.

i threw together some spaghetti
.GitHub - jeremy-coleman/budo2

2 Likes

Seems now it is a good time to ask about it, finally :slight_smile:

Sure! Was there a specific question you had in mind?

  1. The choice for the Input class.
  2. The choice of physics engine.
  3. How much it may be less perf (if yes; approximately) than the default collision system?

Good questions.

  1. The Input class is just a bespoke encapsulation of Babylon’s new input system. I structured my encapsulation very similarly to Unity’s old Input class just for ease of use, but the basic idea is to encapsulate Babylon’s extremely general input system into a smaller contract that provides only the things you need for your specific scenario, thus allowing you the convenience of your own contract and calling conventions while still leveraging the Babylon-recommended way to get user input.
  2. Ammo.js is my physics engine of choice for a number of reasons, prominently support and stability: the library is actually Bullet compiled to WebAssembly by kripken, one of the most prominent contributors to WebAssembly itself. Thus, Ammo.js has behind it one of the largest and most proficient communities of any open source physics engine. However, in this particular case it also had something else I needed that is, as far as I know, not possible in many other Web-usable physics engines: in lines 85 through 96, I reach through Babylon’s physics abstraction and into Ammo.js directly in order to selectively lock certain attributes of the underlying physics imposter, specifically rotation. This is necessary because the character controller needs to react physically in translation space (being knocked aside by the boxes, running into walls, etc.) while simultaneously being unreactive in rotation space (otherwise the character controller would fall over). Again, this is a direct usage of features in Ammo.js which are not available in some other physics engines.
  3. I’m not super familiar with Babylon’s built-in collision system, but my understanding of it is that it’s quite old, JavaScript-based, and really intended for simple scenarios. It is not, as I understand it, intended to be used in conjunction with a real physics engine because a physics engine must necessarily have its own collision system. Regarding perf, I would expect Ammo.js to be much more performant (and feature-rich) for complex scenarios because (1) it’s a well-established full-featured physics engine with a huge support community and (2) it runs in WASM, which can provide dramatic performance improvements over JavaScript for math-intensive operations. In short, I expect Ammo.js to be much better suited to this task performance-wise than the default collision system because Babylon’s built-in collisions were never really intended to do this sort of thing, whereas full-on physics simulation is exactly what Ammo.js does best.
6 Likes

Thank you very much for your detailed answer.
From my practice, the built-in Babylon collision system works perfectly for simple cases of 3D interactions (walls, obstacles etc) and the code is very simple and convenient to use.
Still after your examlpe I am more and more inclined to test Ammo.js in some environments.
What is the recommended way to use it with GLB levels models (where a ‘player’ is inside a model)?
Another question - how to use ArcRotateCamera with physics collisions?

1 Like

The short answer is that I don’t know yet, at least not for sure. This exact set of problems is part of what I’ll be exploring when we make the golden path for the “walking simulator,” likely shortly after 5.0 release. I can tell you that what I think I’ll recommend is having specially-marked (by name or other mechanism) geometry in the glTF that the loading code can then find and turn into physics impostors. This will allow complete control of the collision system directly from the DCC tools used to produce the assets and remove the difficulties of trying to hand-craft physics entities in Babylon itself. However, I’ve not actually tried this, and it will likely be a few months before I get a chance to do so in the context of the “walking simulator” golden path. That’s definitely on the radar, though!

Regarding using an ArcRotateCamera with physics collisions, my honest recommendation would be to not attempt it. I don’t really know what the desired behavior for such an interaction would be, but generally speaking I wouldn’t advocate trying to mix physics (which tries to control the behavior of objects) with Babylon’s utility cameras (which have highly specialized behaviors all of their own). If all you want to do is keep the camera centered on a character, you could probably use an ArcRotateCamera for that, but I wouldn’t try to add physics to it. If you want to make it avoid clipping through walls, your best bet is probably a per-frame raycast from the character toward the camera to determine the correct distance. If your environment is fully robust physics-wise (i.e., absolutely everything has an imposter) then that raycast might be done within the physics system; but if your physics environment is more sparse (i.e., impostors elided on high ceilings, etc. that players can’t collide with but cameras might), then it might be more appropriate to use Babylon’s built-in mesh-based collision system for that specific raycast.

Hope this helps, and best of luck!

4 Likes

I would suggest trying a couple of things here. @syntheticmagus has good points regarding Ammo so no need to repeat them :sunglasses:

To get the camera collisions I would set the cameras parent to the head sub mesh (or create an x form node) and scale out the sub mesh bounding box a bit.

I would also assign an impostor type of mesh impostor for the dude mesh if you haven’t already since Ammo is happy to use a mesh collider

HTH!

1 Like

From some time this wonderful example stopped to work because Property 'DeltaHorizontal' does not exist on type 'typeof PointerInput'. :frowning: