Collision problem

Hi, I’m trying to make an entity not solid when player from a team goes through it. And it works, but after 5sec, everything no collide with everything (even the world) so props goes through the ground, into the void
Here is my code, I don’t know what is wrong


	hook.Add("ShouldCollide", "collidealiens", function(ent1, ent2)

		if (ent1:IsPlayer() or ent2:IsPlayer()) and ((ent1:GetClass() == "ent_xenowall" or ent2:GetClass() == "ent_xenowall") or (ent1:GetClass() == "ent_egg" or ent2:GetClass() == "ent_egg")) then
				
			if ent1:IsPlayer() then ply = ent1 
			elseif ent2:IsPlayer() then ply = ent2 
			end

			if (ply:Team() == TEAM_ALIENS_SCOUT or ply:Team() == TEAM_ALIENS or ply:Team() == TEAM_ALIENS_ALPHA or ply:Team() == TEAM_ALIENS_OUVRIER) then
				if IsValid(ply:GetActiveWeapon()) and not (ply:GetActiveWeapon():GetClass() == "gmod_tool" or ply:GetActiveWeapon():GetClass() == "weapon_physgun") then
					return false
				elseif not IsValid(ply:GetActiveWeapon()) then
					return false
				end
			else return true

			end

		else return true

		end

		if ent1:GetClass() == "ent_xenowall" and ent2:GetClass() == "ent_xenowall" then
			return false
		else
			return true
		end

	end)

Probably related http://wiki.garrysmod.com/page/Entity/CollisionRulesChanged

Basically, what you need to do is call CollisionRulesChanged ANYTIME the shouldcollide will return something different for that entity than it has before.

You don’t want this logic inside the ShouldCollide hook as it can crash your server. You also don’t want the statements deciding if it should pass or not in there.

You should set it up in a Think function to determine when ent1 should or shouldn’t collide with the player. That shouldn’t be in should collide hook at all.

Something like this maybe: (UNTESTED CODE)



--On your ent_xenowall, should be shared
function ENT:PlayerPassesFilter(ply)
	if (ply:Team() == TEAM_ALIENS_SCOUT or ply:Team() == TEAM_ALIENS or ply:Team() == TEAM_ALIENS_ALPHA or ply:Team() == TEAM_ALIENS_OUVRIER) then
		if IsValid(ply:GetActiveWeapon()) and not (ply:GetActiveWeapon():GetClass() == "gmod_tool" or ply:GetActiveWeapon():GetClass() == "weapon_physgun") then
			return false
		elseif not IsValid(ply:GetActiveWeapon()) then
			return false
		end
	else
		return true
	end
end
function ENT:Think()
	if (!self.collisionFilter) then self.preCollisionFilterNum = 0; else self.preCollisionFilterNum = #self.collisionFilter; end
	self.collisionFilter = {};
	for k, ply in pairs(player.GetAll()) do
		if (!self:PlayerPassesFilter(ply)) then
			table.insert(self.collisionFilter, ply);
		end
	end
	
	if (#self.collisionFilter != self.preCollisionFilterNum) then --Update if something has changed. 
		self:CollisionRulesChanged();
	end
end

--Should be shared.
hook.Add("ShouldCollide", "filterCollisions", function(ent1, ent)
	local ent, ply;
	if (ent1:GetClass() == "ent_xenowall") then ply = ent2; ent = ent1; end
	if (ent2:GetClass() == "ent_xenowall") then ply = ent1; ent = ent2; end
	
	if (IsValid(ent) && IsValid(ply) && ply:IsPlayer())then
		if (ent.collisionFilter) then
			for k, v in pairs(ent.collisionFilter) do
				if (v == ply) then return false; end
			end
		end
	end
end)


Thanks, I’ll try that this afternoon

thanks a lot ! It works.