• Propper use of ShouldCollide
    6 replies, posted
How exactly should one use [URL="https://wiki.garrysmod.com/page/GM/ShouldCollide"]ShouldCollide[/URL] hook? Because everytime I try to use it, it breaks the physics, or crashes the server... We need better documentation! Also it doesn't break the physics instantly, but it happens overtime... [B]For example: [/B] This code breaks the physics [CODE] someEntity:SetCustomCollisionCheck( true ) local ncProp = {} -- Just a table of random props hook.Add("ShouldCollide", "Test", function(ent1, ent2) if not ncProp[ent1] and not ncProp[ent2] then return end return false end) [/CODE] and this one too [CODE] someEntity:SetCustomCollisionCheck( true ) someEntity:CollisionRulesChanged() local ncProp = {} -- Just a table of random props hook.Add("ShouldCollide", "Test", function(ent1, ent2) if not ncProp[ent1] and not ncProp[ent2] then return end return false end) [/CODE] Crashes the server [CODE] someEntity:SetCustomCollisionCheck( true ) local ncProp = {} -- Just a table of random props hook.Add("ShouldCollide", "Test", function(ent1, ent2) if not ncProp[ent1] and not ncProp[ent2] then return end ent1:CollisionRulesChanged() return false end) [/CODE] This one too crashes the server... [CODE] someEntity:SetCustomCollisionCheck( true ) local ncProp = {} -- Just a table of random props hook.Add("ShouldCollide", "Test", function(ent1, ent2) if not ncProp[ent1] and not ncProp[ent2] then return end ent1:CollisionRulesChanged() ent2:CollisionRulesChanged() return false end) [/CODE]
flip-flopping collision rules for an entity is bad practice. The ShouldCollide hook is generally intended for unchanging collision rules, such as "entities of type A will never collide with type B" — not "entities of type A will sometimes collide with type B." EDIT: I have also heard that changing collision rules between two entities while they are colliding/penetrating will also break the physics. Even more, someone long ago said they had issues with altering collisions between entities of the same class.
[code]someEntity = Entity(1):GetEyeTrace().Entity someEntity:SetCustomCollisionCheck( true ) hook.Add("ShouldCollide", "Test", function(ent1, ent2) if ent1 == game.GetWorld() || ent2 == game.GetWorld() then return end if ent1.ShouldCollideTest || ent2.ShouldCollideTest then return false end end) timer.Create("Test", 1, 0, function () someEntity.ShouldCollideTest = !someEntity.ShouldCollideTest someEntity:CollisionRulesChanged() end)[/code] CollisionRulesChanged should be called after you change the conditions when it should collide, not in the shouldcollide hook. I assume breaking the physics was stuff falling through the floor. The world counts as an entity, so you removed collisions with the world.
[QUOTE=Mechanical Mind;50815170][code]someEntity = Entity(1):GetEyeTrace().Entity someEntity:SetCustomCollisionCheck( true ) hook.Add("ShouldCollide", "Test", function(ent1, ent2) if ent1 == game.GetWorld() || ent2 == game.GetWorld() then return end if ent1.ShouldCollideTest || ent2.ShouldCollideTest then return false end end) timer.Create("Test", 1, 0, function () someEntity.ShouldCollideTest = !someEntity.ShouldCollideTest someEntity:CollisionRulesChanged() end)[/code] CollisionRulesChanged should be called after you change the conditions when it should collide, not in the shouldcollide hook.[/QUOTE] Oh, I see. But what if I the code doesn't know whether it will return true or false prior ShouldCollide hook? Or am I supposed to loop trough all entities to get those conditions?
You should do something similar to what I've done, inside another hook (e.g. think), when you want to change whether an entity should collide, set a variable on the entity and call CollisionRulesChanged. Then the should collide hook would decide based upon the variable you set, as in my example. Also given that ShouldCollide can break the game, I would keep the logic inside of it simple so there's less chance of a bug causing problems in uncommon situations.
[QUOTE=Mechanical Mind;50815212]You should do something similar to what I've done, inside another hook (e.g. think), when you want to change whether an entity should collide, set a variable on the entity and call CollisionRulesChanged. Then the should collide hook would decide based upon the variable you set, as in my example. Also given that ShouldCollide can break the game, I would keep the logic inside of it simple so there's less chance of a bug causing problems in uncommon situations.[/QUOTE] The documentation says "Prior returning false, call ENT:CollisionRulesChanged()". Can ENT:CollisionRulesChanged() be called for other than returning false? Like returning nil or true?
[QUOTE=edgarasf123;50815236]The documentation says "Prior returning false, call ENT:CollisionRulesChanged()". Can ENT:CollisionRulesChanged() be called for other than returning false? Like returning nil or true?[/QUOTE] Call it whenever the Collision Rules have changed.
Sorry, you need to Log In to post a reply to this thread.