Directional platforms help

found it

This is what I always do.

I haven’t experienced this myself, but I guess it’s very much up to how you deal with your player control and physics code.

1 Like

Box2D is sometimes a bit funny when two vertices from separate fixtures are put on top of each other, which I suppose is causing this issue in the first place?

If so, could one solution be to optimise the tile > fixture conversion happening behind the scenes?

1 Like

I checked his y velocity as well as his current command from the player.
his states are
state_normal with sub-states [stand, stand_shooting, run, run_shooting, jump, jump_shooting, fall, fall_shooting]
and
state_rocket with sub-state [flying, flying_shooting]
and
state_dead

if his velocity.y > 0 then he’s in the jump state, less than 0 then fall state. if he’s currently firing a weapon with those cases true then set state to its shooting variants etc

I could try putting the condition to check if the velocity is below a negative value. Ill try that

@chevgc were you able to get this to work? I use a sphere which works to a degree, but I also get issues with the incorrect collisions triggering (probably caused by the invisible seams in Box2D where two tiles meet).

When using raycasting to figure out collisions, how do I get the position and size of the collision object so I can query the world?

The plan is to send raycasts in these eight directions every frame, to get which sides of the collision object that are colliding.

Artboard

Collision Object components don’t have a position themselves. The collision shapes on the collision object have positions and sizes, but unfortunately there’s no way to get these at runtime. You will have to hard-code those. I also suggest you start the raycasts slightly inside the shape, instead of from exactly at the corners (have a variable ‘overlap’ parameter), since they have to start outside any colliding object to detect it.

You can probably get away with fewer rays than that too. The issue with inside/overlapping edges is generally only a problem for the ground, since gravity is constantly forcing the player into it.

2 Likes

Thanks @ross.grams, that’s a bummer! I’m used to Gideros, another Lua SDK, where all variables are always available (as well as the entire Box2D API), so I’m trying to wrap my head around Defold’s way of doing things. Not a fan of hard coded vars, because it makes collaboration with artists harder.

Objects tend to get stuck to the sides of walls too, so it’s probably best to use one system determining collisions, for consistency.

I didn’t think to mention it before, but you can use script properties to expose those variables to the editor if that makes it easier for you.

2 Likes

It would! How do I tap into that magic?

Check documentation for go.property() and the script properties manual: https://www.defold.com/manuals/script-properties/

2 Likes

Raycasts now work great to determine which direction the player is colliding with.

However, the bug @ross.grams details above, is a showstopper to me. Is there a way of adding issues in Github that are not relating to editor 2?

Which issue is that? Describe it and I’ll create a ticket in out issue tracker.

Thanks! Nabbed the image from the post above:

Dynamic collision objects can get stuck between tiles of a Tilemap collision object.
ground_side_normal_issue

This is probably (I’m guessing here) because each tile is converted to one Box2D fixture behind the scenes, rather than one larger fixture describing a block of tiles:

4 Likes

Like the composite collider in unity… ?

I just read up on composite collider, and yeah, seems exactly what I’m after. Although the composite collider is synchronous and seems a big feature in its own right. I’m simply after a fix for the bug where dynamic objects get stuck and incorrect collision responses are fired.

Are you having problems with dynamic objects or kinematic objects?

One big reason why the tile collision works the way it does, is that it’s dynamic in its nature. You can at any time change a tile, and therefore its physics.

1 Like

Oh blimey, that’s good to know too! I can consistently replicate the issue with both kinematic and dynamic bodies.

In my case dynamic bodies are more important, because I want to save time by not coding the collision responses myself.

Just to be clear, this is not a “bug”! Box2D is working exactly the way it should be.

Because Defold treats each tile as a separate shape (for good reasons), life is a bit more difficult than you might expect, but it’s not all Defold’s fault either. Nor is this just a problem with tilemaps. Any time you want to build a continuous surface out of multiple pieces you’ll run into this. Unfortunately, no physics engine can read your mind.

Given two overlapping bodies, the physics engine will calculate the shortest distance and direction necessary to move those bodies so they won’t overlap anymore. It doesn’t really ‘prevent’ overlaps, it just moves them apart before things are rendered. With two rectangles, the normal of the contact will be vertical or horizontal depending on the amount of overlap in each direction.

tilemap_physics_1

In most cases, gravity is going to cause a vertical overlap every frame that something is ‘resting’ on the ground. As your body moves across a seam in the ground, this vertical overlap will be larger than the horizontal overlap from the seam for possibly a frame or two, giving you a horizontal contact normal.

tilemap_physics_2

The deeper the vertical overlap (because of low framerate or something), the worse it is.

tilemap_physics_3

Of course it happens with regular objects too (no tilemap)

tilemap_physics_5

For most games it’s not really possible to simply avoid this issue by making every floor a single continuous shape. It’s pretty much guaranteed in any infinite runner or any other platformer where the levels are made in separate pieces. And for example what if you want a one-way platform sticking off the end of a solid platform? Those two bodies must have different properties, there’s no way for them to be a single shape.

Any robust platformer (with any engine) is going to have to deal with this issue. A specialized ‘physics engine’ like Bump might help—meaning that someone else solved the problem for you.


I think you will find that using a dynamic body for your player will be much more work in the long run, especially considering the limited subset of Box2D’s features that Defold gives you access to. With a dynamic body you will have to deal with forces and friction, you can’t just move the player where you want, you can’t change collision groups at runtime so I’m not sure how you would do one-way platforms, etc. Kinematic bodies let you skip all that stuff. You can control them just like any other game object, but they give you detailed collision information (which you can use or ignore as you like).

16 Likes