Directional platforms help

So Ive had this problem for a while. I followed and implemented this example for allowing the player to jump through platform and walk on top of them.

CODE: [https://github.com/britzl/publicexamples/blob/master/examples/one_way_platforms/one_way_platforms/one_way_platforms_player.script]

This worked perfectly in the prototyping phase. But as soon as my levels became larger and had more game objects(enemies walking around, moving platforms, pickups etc) The player sometimes fall through platforms while walking on them. I could share my player script but its 940 lines long! I tried running debug and it seam the y normal randomly flips to 90 degrees(horizontal arrow). I tried printing the normal while the player is on the platforms but it always reads (0,1,0) which is what its suppose to be so im a bit confused.

I also checked the game project setting and tried increasing the Max Collisions and Max Contacts without any luck. I’m not sure what to try next. Is it some kind of memory leak issue maybe?

You can enable the debug physics rendering, to more clearly see what is happening. You find it under the game.project settings.

2 Likes

I did.

The normal.y sometimes flips horizontally which causes the fall but the point was it didnt happen before. As if the physics accuracy took a hit after adding so much go’s to the levels.

Is it falling through the middle of a single, solid platform, or at a joint between shapes/bodies?

1 Like

I was paying attention to that as well its usually between 2 tiles of the platform. but the collision shapes are perfect 90 degree edges.

debugoff

debugon

If I walk back on forth on the platform I eventually fall through it

Yeah, I bet that’s your problem then. You player body can contact those inside edges and give you a sideways normal.

ground_side_normal_issue

Honestly I don’t think I’ve ever found a really great solution for this. You can try making your player’s collision rounded or beveled on the bottom. You can try to make checks to ignore these contacts, with some sort of threshold, or have vertical contacts override horizontal ones . . .

Actually I think the only reliable way to deal with this is to rely on raycasts instead of contact point responses.

1 Like

Yes, I’ve also spent quite a lot of time trying to deal with this problem. Sphere shape or ray cast is currently the way to go.

3 Likes

Using Rounded collision seams to do the trick but now the player is twitching each time I pass between 2 platform tiles i.e trying to switch to his fall state then back to running state. Ill try the adjust the normal and see what happens.

by the way I never used Ray cast before is there an example use case in the docs?

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