How to improve kinematic collisions and avoiding glitching caused by moving objects/ in general?

Hey, I’m trying to make a game with integrated modding (if it doesn’t work, I’ll just scrap it and make it open source). Because of this I have to make the collision areas multiple objects because you can’t unevenly scale collision objects. I tried using triggers, but they didn’t work well and sometimes I couldn’t move when I needed to. Now I’m trying to use a kinematic object, but I’m also having problems with this.

Video Example

Here’s the code:

function init(self)
     self.comp = vmath.vector3(); self.correction = vmath.vector3()
end

function update(self, dt)
	 --[[ unimportant
        self.fps.update()
	label.set_text("/player#label", tostring(math.floor(1/dt)))
	local speed = 500
	if vmath.length_sqr(self.dir) > 1 then
		self.dir = vmath.normalize(self.dir)
	end
	local p = go.get_position()
	local change = p + self.dir * speed * dt
	go.set_position(change)

	self.dir.x = 0; self.dir.y = 0; self.dir.z = 0--]]

	go.set_position(go.get_position() + self.comp)

	globals.clearVector(self.correction); globals.clearVector(self.comp) --globals is an imported lua module
end

function on_message(self, message_id, message, sender)
	if message_id == hash("contact_point_response") then
		if message.distance > 0 then
			local proj = vmath.project(self.correction, message.normal * message.distance)
			if proj < 1 then
				local comp = (message.distance - message.distance * proj) * message.normal
				self.comp = comp
				self.correction = self.correction + comp
			end
		end
	end
end

Anything I can do to improve collisions? Thanks.

It was a bit hard for me to see what the problem was in the video. Is it possible to test an HTML5 demo?

Although…

This looks slightly different from the recommended way of resolving kinematic collisions. In your code you only apply self.comp once in update(), not each time a collision is resolved. If you look at the manual about resolving collisions you see the position updated each time:

      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
        -- Apply compensation
        go.set_position(go.get_position() + comp)
        -- Accumulate correction done
        self.correction = self.correction + comp
      end
1 Like

Alright, I changed it and it’s working better. Thanks!

2 Likes