Need help with raycast based collusion system

I am workin on a non physics based character controller.
As the title says, I am using raycasts to detect collusion. It works fine when there are only a couple of characters .The problem Im having is when there are a lot of characters colliding wirh each other. The characters pushing each other creates a “vibration”, that builds up over time and eventually ends up pushing the charactes into walls. I dont really have a clue of what to do. How can I fix this? Thanks in advance
code ( cm for character motor)

local cm = {}
cm.__index = cm

--variable
cm.targetPos = Vector3.zero
cm.input = Vector3.zero
cm.velocity = Vector3.zero
cm.falling = false

--setting
cm.walkSpeed = 20
cm.gravity = 2

--internal_variables
cm._minMove = 0.01
cm._rayMultiplier = 1.5
cm._hitboxRadius = 1
cm._hitboxHeightHalf = 1
cm._hitboxSideRays = {}

function cm:update(dt)
	local currentPos = self.hitbox.Position
	local diff = self.targetPos - currentPos
	local diffXZ = diff * Vector3.new(1, 0, 1)
	local diffXZMag = diffXZ.Magnitude
	
	local velocity = Vector3.zero
	local prevVelocity = self.velocity
	
	--calc walk
	if diffXZMag > self._minMove then
		if diffXZMag > self.walkSpeed * dt then
			velocity = diffXZ.Unit * self.walkSpeed * dt
		else
			velocity = diffXZ
		end
	end
	
	--gravity
	if self.falling then
		velocity += Vector3.yAxis * ( prevVelocity.Y - (self.gravity * dt) )
	end
	
	--check ground collusion
	local groundCastResult = workspace:Raycast(
		currentPos + velocity, 
		Vector3.yAxis * -1 * self._rayMultiplier * self._hitboxHeightHalf,
		self._rayPara
	)
	if groundCastResult then
		local dist = groundCastResult.Distance
		local diff = dist - self._hitboxHeightHalf
		if diff > self._minMove then
			self.falling = true
		elseif diff < self._minMove then
			self.falling = false
			velocity -= Vector3.yAxis * diff
		else
			self.falling = false
		end
	else
		self.falling = true
	end
	
	--check side collusion
	local sidePush = Vector3.zero
	for i, vec in ipairs(self._hitboxSideRays) do
		local result = workspace:Raycast(currentPos + velocity, vec * self._hitboxRadius * self._rayMultiplier, self._rayPara)
		if result then
			local dist = result.Distance - self._hitboxRadius
			if dist < 0 then
				sidePush += vec * dist
			end
		end
	end
	
	velocity += sidePush
	
	--apply min move
	local and = Vector3.yAxis
	if math.abs(velocity.X) > self._minMove then
		and += Vector3.xAxis
	end
	if math.abs(velocity.Z) > self._minMove then
		and += Vector3.zAxis
	end
	 velocity = velocity * and
	
	self.velocity = velocity
	self.model:TranslateBy(velocity)
end

function cm.new(m)
	local new = {
		model = m,
		hitbox = m.PrimaryPart,
		_hitboxHeightHalf = m.PrimaryPart.Size.Y / 2,
		_hitboxRadius = math.max(m.PrimaryPart.Size.X/2, m.PrimaryPart.Size.Z/2),
		
		targetPoint = m.PrimaryPart.Position
	}
	setmetatable(new ,cm)
	new._hitboxSideRays = {
		Vector3.new(1, 0, 0),
		Vector3.new(-1, 0, 0),
		Vector3.new(0, 0, 1),
		Vector3.new(0, 0, -1)
	}
	
	local rayPara = RaycastParams.new()
	rayPara.IgnoreWater = true
	rayPara.FilterDescendantsInstances = {m}
	new._rayPara = rayPara
	
	return new
end

return cm

video

i suggest using pathfinding service instead of raycast to detect collision or you can use regions to detect collisions and then you can blacklist specific names

Hmm… If i understand you correctly, the solution is to avoid mass collusion in the first place? I guess that could work.

I’d probably recommend a workflow like this:

  • Check for a collision
  • No Collision?
    • Keep moving
  • Collision
    • Don’t advance any further

That’s what I had at first but it had a few problems

  1. The character would stop at a angled wall. Even if they could still move forward diagonally.
  2. The character would not get pushed by moving walls
  3. Didn’t really solve collusion issues between characters.

I found a solution online. Thanks for your help anyway.
2d Collusion Engine