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 :slight_smile:

–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