 # Problem resolving kinematic collisions

#1

I used the described collision handling with a kinetic player objekt and a static wall.
when a player hits the wall his vector is corrected. it works, yet i see bouncing, when the player hit a corner of a square or sometimes in general when you press (top and right) and strafe along the wall.

Does anyone know a solution where less bouncing (correction) is done?
video imgur

``````   if message.distance > 0 then
if message_id == hash("contact_point_response") then
local proj = vmath.project(self.correction, message.normal * message.distance)
if proj < 1 then
-- Only care for projections that does not overshoot.
local comp = (message.distance - message.distance * proj) * message.normal
go.set_position(go.get_position() + comp)
-- Accumulate correction done
self.correction = self.correction + comp
end
end
``````

player go (for settings of physics)

``````embedded_components {
id: "collisionobject"
type: "collisionobject"
data: "collision_shape: \"\"\n"
"type: COLLISION_OBJECT_TYPE_KINEMATIC\n"
"mass: 0.0\n"
"friction: 3.0\n"
"restitution: 3.0\n"
"group: \"player\"\n"
"mask: \"enemyshot\"\n"
"mask: \"nonwalkable\"\n"
"mask: \"coin\"\n"
"embedded_collision_shape {\n"
"  shapes {\n"
"    shape_type: TYPE_SPHERE\n"
"    position {\n"
"      x: 1.0\n"
"      y: 22.0\n"
"      z: 0.0\n"
"    }\n"
"    rotation {\n"
"      x: 0.0\n"
"      y: 0.0\n"
"      z: 0.0\n"
"      w: 1.0\n"
"    }\n"
"    index: 1\n"
"    count: 1\n"
"  }\n"
"  data: 22.0\n"
"  data: 22.0\n"
"}\n"
"linear_damping: 3.0\n"
"angular_damping: 3.0\n"
"locked_rotation: false\n"
""``````
0 Likes

#2

Hard to say what’s wrong. Can you please share the project (zip here) or a minimal repro case?

0 Likes

#3

I got a solution. by not compensating like the script suggested.
now i am using raycasts to test if a wall is next to player. if yes, the move towards the direction is forbidden. its very smooth atm and the player speed is not affected when wallstrafing. (press right and top together, once player hits wall to the right, the top-movement is still in full speed).

i guess the main problem is the sequence of the example. because normally
the actual move and the test if something was hit by the move (and the compensation tactic) would need all to be done before the next draw call. so the player wouldnt see any jumping inside and correcting outside the wall. in the example, the compensation is done, after the hit occured. thus jumping can occur.

for anyone to check, here is the implementation i did, yet its not a wonderful one –Using two raycasts per direction, because the player has a height and needs to be checked on
–top and on bottom of sprite if moving right e.g.

``````elseif action_id == hash("right") then

r1_startvec=vmath.vector3(self.wpos.x,self.wpos.y-18,2)
r1_endvec=vmath.vector3(self.wpos.x+18,self.wpos.y-18,2)
r2_startvec=vmath.vector3(self.wpos.x,self.wpos.y+18,2)
r2_endvec=vmath.vector3(self.wpos.x+18,self.wpos.y+18,2)
r1=physics.raycast(r1_startvec,r1_endvec,{hash("nonwalkable")})
r2=physics.raycast(r2_startvec,r2_endvec,{hash("nonwalkable")})
if r1 == nil and r2 == nil then
self.inputvect.x =  1
else
self.inputvect.x =  0
end
end
``````

And in the update function, rendercam using:

``````    function update(self, dt)
self.wpos = go.get_position()
if vmath.length(self.inputvect) ~= 0 then
local vect = vmath.normalize(self.inputvect)
self.wpos = self.wpos + vect * self.sumspeed * dt
go.set_position(self.wpos)
end
msg.post("main#screen_widget", "set position", {pos = self.wpos})
self.spos = rendercam.world_to_screen(self.wpos)
end``````
0 Likes