Player gets stuck when moving horizontally


#1

Hi, I’m using the exact same code as the platformer tutorial as I’m not pretty good with physics. I took a video of how this looks.

Btw I’m using @britzl’s orthographic camera, pretty cool and easy to use.

If it helps this is the code I’m using for the player (kinematic).

-- player.script
----
local move_acceleration = 3500
local air_acceleration_factor = 0.8
local max_speed = 450
local gravity = -1000
local jump_takeoff_speed = 550
local fall_multiplier = 2.5
local low_jump_multiplier = 2


local msg_contact_point_response = hash("contact_point_response")
local group_obstacle = hash("obstacle")
local input_right = hash("right")
local input_left = hash("left")
local input_jump = hash("jump")



function init(self)
	msg.post(".", "acquire_input_focus")

	self.velocity = vmath.vector3(0, 0, 0)
	self.correction = vmath.vector3()
	self.ground_contact = false
	self.move_input = 0
	self.anim = nil
end


function final(self)
	msg.post(".", "release_input_focus")
end


function update(self, dt)
	local target_speed = self.move_input * max_speed
	local speed_diff = target_speed - self.velocity.x
	local acceleration = vmath.vector3(0, gravity, 0)
	if speed_diff ~= 0 then
		if speed_diff < 0 then
			acceleration.x = -move_acceleration
		else
			acceleration.x = move_acceleration
		end

		if not self.ground_contact then
			acceleration.x = air_acceleration_factor * acceleration.x
		end
	end

	local dv = acceleration * dt
	if math.abs(dv.x) > math.abs(speed_diff) then
		dv.x = speed_diff
	end

	local v0 = self.velocity
	self.velocity = self.velocity + dv

	local dp = (v0 + self.velocity) * dt * 0.5

	-- Make jump look more natural
	if self.velocity.y < 0 then
		self.velocity.y = self.velocity.y + gravity * (fall_multiplier - 1) * dt
	elseif self.velocity.y > 0 then
		self.velocity.y = self.velocity.y + gravity * (low_jump_multiplier - 1) * dt
	end

	-- Apply all this before
	go.set_position(go.get_position() + dp)

	-- Reset volatile state
	self.correction = vmath.vector3()
	self.move_input = 0
	self.ground_contact = false
end



function handle_obstacle_contact(self, normal, distance)
	local proj = vmath.dot(self.correction, normal)
	local comp = (distance - proj) * normal
	self.correction = self.correction + comp
	go.set_position(go.get_position() + comp)

	if normal.y > 0.7 then
		self.ground_contact = true
	end

	proj = vmath.dot(self.velocity, normal)
	if proj < 0 then
		self.velocity = self.velocity - proj * normal
	end
end


function on_message(self, message_id, message, sender)
	if message_id == msg_contact_point_response then
		if message.group == group_obstacle then
			handle_obstacle_contact(self, message.normal, message.distance)
		end
	end
end



function jump(self)
	if self.ground_contact then
		self.velocity.y = jump_takeoff_speed
	end
end

function abort_jump(self)
	if self.velocity.y > 0 then
		self.velocity.y = self.velocity.y * 0.4
	end
end

	
function on_input(self, action_id, action)
	if action_id == input_left then
		self.move_input = -action.value
	elseif action_id == input_right then
		self.move_input = action.value
	elseif action_id == input_jump then
		if action.pressed then
			jump(self)
		elseif action.released then
			abort_jump(self)
		end
	end
end

#2

This may be the problem Directional platforms help


#3

That was it, since I do not know how to do raycast collisions … guess I’ll just use several shapes for the floor.