Jump to content

Character movement and collision


Recommended Posts


i just started a little testproject with babaylon. No big thing, just walking around in a Level an collecting items.

When i was doing a prototype i looked a the playground examples. The collision-example is quite close to what i want to achieve:


you can run around, land on the ground and can't walk through obstacles. This is what I want for my player object. So i created, as in the example, a surface as a floor, a couple of boxes as obstacles and a ball as a player. I activated collision detection for the scene and all objects, gravity and a asigned vector, but nothing happened. If I now move objects using locallyTranslate() there will be no collision between the objects.


I just think I misunderstood something and so I wanted to ask here what the correct way is to implement a character walking arround in a level.

Link to comment
Share on other sites

Hiya S, and welcome.  I have done SOME mesh-to-mesh collision play... using the built-into-BJS collision system (non-physics engine)...


Use W A S D Q E keys to move LEFT cylinder, and SHIFTED W A S D Q E keys to move right cylinder.

Although it is not needed, I put an actionManager intersection tester on one of the cylinders.  *shrug*  Something to play-with.

Included in this playground are two "tool functions" to make it easier to see and position the mesh's invisible .ellipsoid area/volume.

These tools are not well coded (by me).  They are, at best, alpha-grade. 

So, that playground is essentially a mesh-to-mesh collision testing scene.

BUT... I'm quite sure that this collision system... was not meant for mesh-to-mesh collisions.  It is/was designed for freeCamera-to-mesh collisions (first-person shooters?).

Mesh are never affected by scene.gravity (unless a third-party physics engine is used, such as CannonJS or OimoJS, both available to BJS scenes).

So, you probably didn't use camera.applyGravity = true;  ...yet (freeCams only, I believe).  And then... if your camera starts-out above the collision-active ground, you need camera._needMoveForGravity = true;   ... to make the camera start falling as soon as the scene finishes loading.

Pretend that one of the cylinders is a player, and the other is an obstacle.  Notice that I do not use the free camera controls to move the cylinder (via parenting cylinder to camera).  Instead,  I move the cylinder itself... with nav keys  This makes it easier to test TRUE mesh-to-mesh collision, and keep the camera completely un-involved (for now).

There is also a property on mesh and freeCamera called .ellipsoidOffset.  This vec3 local-Space value moves the mesh or freeCamera collision .ellipsoid... forward/backward/left/right/up/down... away-from actual mesh or camera position... some amount.

So, you could set camera.ellipsoidOffset so that its .ellipse collider is in-front-of camera, instead of encircling it.  I dunno what that will solve.

If you place/parent a sphere (player) in-front-of camera (at same place as camera.ellipsoidOffset, it might block the camera's view.  No good.

If you place the ellipsoidOffset TOO far in-front-of camera (and maybe position a parented-to-cam sphere at that location as well), it might make the game play strangely.


Our friend @BitOfGold (I think) coded a cool 3D PacMan-like thing... which I think works real nice (follow camera, I think).  You should borrow some code from there.


Collision detection is always a challenge.  Don't forget the actionManager...

    barrel2.actionManager = new BABYLON.ActionManager(scene);

        new BABYLON.ExecuteCodeAction({ trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, parameter: barrel1},
        function (bjsEvent) {
            // do stuff, like reverse camera/player to PREVIOUS non-intersection position

It doesn't use .ellipse, or ellipsoidOffset, or .moveWithCollisions(), enableCollisions, checkCollisions, none of it.  This just watches for intersections between mesh, even invisible spheres that are parented "around" a camera.  Hint hint.

And, with all collisions... watch out for continuous collision between ground, and cameras/mesh sliding across ground.

I hope I have been helpful.  SO much to think-about, eh?  *nod*  Collision-detection/processing is one of the most difficult parts to video games.  Stay tuned... others will comment, I'm sure.

Link to comment
Share on other sites

Heya!  I would say.... follow that #256 playground method.  https://www.babylonjs-playground.com/#LYCSQ#256

That little yellow pacman-like character... stays on the floor and collides with walls... nicely, right?

Notice that the author DID use .moveWithCollisions() (line 195) and .checkCollisions (line 135), so pacman demo is using the same collision system as you are testing.

Yet, the author never changed player or wall .ellipsoid sizes or .ellipsoidOffset.  All those are using "default" settings.  That is pretty nice, huh?

The demo has a rather large "renderLoop"... lines 157-210.  Plenty of study to be done, there.

Have you decided HOW you are going to control your player or "driven objects" yet?  Want to use mouse pointer/buttons for steering and throttle/speed?  Keyboard?  GUI buttons?  Clicks on the ground?

In a way, "how will you collide" is dependent-upon "how will you navigate/move", right?

You are likely still experimenting with various methods.  But perhaps you already have an exact gameplan... as far as camera views, player mesh, and assorted colliding.

You see how large the author's renderLoop is, right?  Lots of testing/forcing can be done in that time... like setting player.position.y = floorHeight+5 (to keep player from falling thru, and then no need to set ground.checkCollisions). 

Same with cameras.  If arcRotateCam, don't let it's .beta go higher than 1.57.  (use arcCam .upperBetaLimit setting) That will keep the camera above the horizon, and never below the floor.  With free/universal cams, keep its position.y above 0.  (just force it to 0 every time thru the renderLoop, perhaps)

For player-moving, I think moveWithCollisions() accepts a vector 3, which has a Y value.  Always set the Y value to 0, and the player won't sink into floor.

Ok, go get 'em.  I won't say that the pacman demo is the best third-person-view bumper-car-like demo I have seen so far in BJS... but it's right up there in the rankings, imho.  It is one of my "gold star bookmarks".  :)

Also, again, wait until approx mid-week... to make any firm decisions.  Try to allow other forum users to give their opinions, because I don't have very much experience with coding games.

Cya later, party on!

Link to comment
Share on other sites

My pleasure.  There is a mesh.rotate(someAxis, someAmount, BABYLON.Space.Local);

Ex:  rotate(new BABYLON.Vector3(1.0, 0.0, 0.0), Math.PI / 2.0, BABYLON.Space.Local);

Ex2:  rotate(BABYLON.Axis.Y, sphere.rotation.x + 2, BABYLON.Space.LOCAL);

This is a Quaternion rotation, but it still does not check for collisions.  There is also a sister .translate() function that is very similar, also not a collision checker.

We really don't have a rotateWithCollisions(), and I think it is because collisions are very dependent upon .position.

There is ANOTHER collision system using a func called "intersectsMesh"  ... http://doc.babylonjs.com/playground/?code=intersectsMesh

But, I would put an actionManager with "onIntersectionEnterTrigger".... on the rotating mesh.  The actionManager is constantly "polled" automatically, watching for intersect with ANY other mesh.  ActionManagers take a few minutes to learn, but once you "see the light", you will LOVE that system.  Very powerful.

For an ACTION on that ActionManager (all actionManagers require a trigger and an action)... use executeCodeAction.  It tells the actionManager to run SOME function that YOU create... if your rotating mesh intersects another mesh.

Inside your somethingCollidedWIthMyRotater() func (if that's what you name it)... you immediately stop rotating (and/or moving position) and block further attempts from the user.  THEN... there is a SLIM possibility that you will be sort-of "stuck in intersect".  Some programmers try to "store" (in constantly-updated variables) the PREVIOUS rotation and position...  whenever a NEW move or rotation is done.  IF an intersect happens, it might be wise to set the rotated mesh .position and .rotation to PREVIOUS step's values... which SHOULD remove it from any intersect condition.


Look at lines 134-143.  Barrel2 has an actionManager with an intersectionEnterTrigger and an executeCodeAction.  Open your JS console, then click on the canvas, then hold down the D key.  Left barrel1 will slide-over and collide-with barrel2.  ActionManager on B2 reports intersect at the JS console.  (yay!)

Now use "A" key to move B1 away-from B2 again.  Now try the "D" key again, collide B1 into B2 again.  NOW the actionManager intersect test... doesn't work anymore.  hmm.

I still haven't determined why.  I might work on that... to see if I can learn why it only works once.

Lots to think about, eh?  Sorry.  I wish I knew more.  I wish I was a better helper.  Stay tuned, keep experimenting.  It sounds like you are on the right track.  Share things you learn, (especially test playgrounds), if you please.  Thx.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...