Deeper explanation of the collision response normal, please?

Hello and happy new year to everybody!

I have a problem with the collision response, I have managed to successfully implement the one-way platform code provided by @britzl in the following post:

But, I have a problem I can not fix because I don’t understand very well the projection-contact-normal value :confused: that is used to calculate the collision point in the given handle_geometry_contact function :disappointed_relieved:

And I have two collateral products as seen in the following capture:

platform_fall.m4v (115.1 KB)

First, the hero falls correctly onto the lower platform,

Then (1) he goes up automatically when he encounters the higher platform,

And then (2) it falls from/through the following lower platform when he has just landed, like if the landing force would have been so strong that it made him go-through the platform…:astonished:

I think it has something to do with the normal, but anyone knows how to fix this?

The code is exactly like the example given in the other post:

function on_message(self, message_id, message, sender)
	if message_id == msg_contact_point_response then
		-- check if we received a contact point message. One message for each contact point
		if message.group == msg_group_ground then
			handle_geometry_contact(self, message.normal, message.distance)
		elseif message.group == msg_group_abyss then
			-- we have fallen into the abyss, reset position
			go.set_position(self.position)
		elseif message.group == msg_group_platform then
			-- If the message normal is pointing up and we didn't have
			-- platform contact from below last frame then we have fallen on top
			-- of a platform and need to treat it like geometry contact
			-- Any other contact with "platform" is considered as contact where the
			-- player is passing through the platform from below
			if message.normal.y > 0 then
				if not self.platform_contact_from_below_last_frame then
					handle_geometry_contact(self, message.normal, message.distance)
					self.platform_contact_from_below = false
				else
					self.platform_contact_from_below = true
				end
			else
				self.platform_contact_from_below = true
			end
		end
	end
end

EDIT: I forgot to mention that the falling through the platform happens even if the hero is running steadily on the platform, as you can see in the following post.

Thank you in advance!

This is the capture for the fall through when running:

The platforms are segments, factory created game objects with kinematic box collision object

There seems to be a problem with box shapes and collisions against the level geometry. Does the player fall through where two platforms align or is it in the middle of a long platform? What if you change from a box to a sphere for the player?

I believe @Mathias_Westerdahl did some investigation around the collision detection? Or maybe that was for tilemaps?

Looking at the animation, it looks like they are separate collision boxes, which would suggest to me that the one you’re falling through is not part of the collision group

My first guess was the same as @Davej had, are you certain they have the correct collision groups?

And, if they are correct, what kind of message info do you get when you are inside the collision ?

print(message_id)
pprint(message)

@britzl, the cases i had most trouble was (is) collision with tilemaps: slopes, and non stitched normals.

Also, I think both your use cases are the same, if you look closely on the left side, there is a “bump” in the second example (from the square box, to the platform(s)), which means that the hero goes up, and after a while falls through:

Does the collision code work if you don’t use the self.platform_contact_from_below value? Will the hero fall through then?

FYI, as an optimisation, one generally doesn’t use kinematic objects for static geometry collision. This is what static is for. Kinematic is used to tell the physics engine that this object might move at some point (like the hero)

1 Like

Thank you all for your replies,

@britzl, yes, the player falls through where two platforms align, they are dinamically created game objects with different widths, but they are stitched together when they are spawned.

@Davej, yes, as I explained to @britzl above, they are separate collision boxes, but they are all the same collision group: “platform”

@Mathias_Westerdahl, I am not at my computer right now so I can not give you all the details you want, but I assume the message_id was the right one because I was reaching the code I posted above in the on_message function and the platform message.group comparison, but tell me, what info are you looking forward to find with the pprint(message) command? also, where in the on_message function do you want me to place it? right at the top (at entrance)? or inside the message.group == platform?
And as you correctly noticed from the capture, in this case they are different platform types, but this situation happens also when the platform types are the same, and some times it doesn’t happen at all, no matter what types of collision boxes they are…
What I noticed by inserting a print(message.normal) inside the message.group == platform, was that it was giving me “correct” values like vector(0, 1, 0) but then suddenly, only once vector(-1, 0, 0) and after that, sometimes, it started to fall through.
Finally, thank you for the tip on the use of kinematic collisions, I thought that they needed to be the same as the hero, but now… the platforms are moving… so, wouldn’t they need to be kinematic?

Thanks again, Cheers!

This is basically what I was wondering about. Basically, if the positions aren’t properly aligned in their Y value, you start to move into your platform. In the first example (first video), the hero slides into a platform, and then suddenly “clamps” to the y value of the platform (Is that intended?).

I’d test without that “jump up through platform” code, and see if that works better.

You can read more about the different collision types in our manual or in the Box2D Manual (See Chapter 6)

1 Like

Yes, I guessed that the hero started to move into the platform at an intersection when I saw the vector(-1, 0, 0) value of the collision normal, and because when I used segments with smaller collision boxes than the hero’s collision box it didn’t happen (or at least I didn’t notice it), but why the unproper alignement? and why it is unproper only some of the times and not all of the times?

You see, when a new platform game object is spawned, it uses the last platform’s position and (other than the big square platform) they all use the same factory with the same collision box sizes, so theoretically, if the new platform uses the last platform’s Y position they should be properly aligned, right? and they are… must of the times at least…

So, the missalignement is in the range of the thousandths of the decimal part of the Y position, right? totally imperceivable to the eye, and then why the more perceivable “bumps” or missalignements between platforms do not make it go through the platform?

And, very important, not all the times that we get the strict/picky/random vector(-1, 0, 0) value the hero goes through the platform.

Then, about: [quote=“Mathias_Westerdahl, post:7, topic:3858”]
I’d test without that “jump up through platform” code
[/quote]

You can see that the code when collision’s message.group == ground goes directly to the geometry handling function and, again, it sometimes produces a “random” vector(-1, 0, 0) value, but it doesn’t make the hero go through the ground, so yes, (I believe) this undesired effect is produced by the message.normal validation done in the message.group == platform code, which, saddly, makes the passable platforms passable… :cry:

In any case, the code for the passable platforms is perfect (thank you @britzl , you the man!) for platforms created at compile time but it does not fit very well with dynamically created platforms made up of various collision boxes, so either I make the dynamic platforms one big game object with one big collision box or I find some other way to implement one-way platforms…

On second thought, the example made by @britzl uses tilemaps… so… what if I make the dynamic platform objects use tilemaps… :thinking: hmmm… interesting…

Anyway, thank you again guys, you are the best! keep it like this!

Cheers!

1 Like