Need to enable/disable collision detection on complex body

Hi,
I seem to be having a lot of trouble at the moment enabling and disabling collision detection on complex bodies. I have a display object with 3 complex physics bodies attached to it. Now, at any one time I only want one of them to be active, and what decides if they’re active or not is the direction in which the character is facing. I started off using “isSensor” but this only seemed to affect the whole body itself (unless I was using this wrong). Also, I see this in the docs regarding “isSensor”…

“Consequently, setting isSensor is set for the entire body. One implication is that for complex physics bodies, where some elements are sensors and some are not, using the body.isSensor property will permanently override the individual body element settings.”
Can somebody please give me a few hints as to what I need to do to solve this? I don’t have any problem with collision detection with the complex bodies, just in the API call(s) that need to be made to only keep one complex body active for collision detection at a time.

Any help would be much appreciated.

Kind Regards [import]uid: 125022 topic_id: 34008 reply_id: 334008[/import]

When checking the collisions, do you have checks for each object the body collides with or do you just check the body?

If you just have one listener that checks the body, you could set up some flags (booleans) and ignore the collision event when does happens:

[lua]local partOneIsActive = true
local partTwoIsActive = false
local partThreeIsActive = true[/lua]

Then, in the collision listener function:
[lua]if (event.element1 == 1 ) and (not partOneIsActive) then return false end
if (event.element1 == 2 ) and (not partTwoIsActive) then return false end
if (event.element1 == 3 ) and (not partThreeIsActive) then return false end[/lua]

I’ve never dealt with multi-body collisions before so I don’t know if this will work exactly as written, but it should be close to what you need. The collision events still fire but they are ignored.

just don’t forget to set the flags when you make parts of the body active/inactive.

-Treb [import]uid: 181948 topic_id: 34008 reply_id: 135283[/import]

Hi Treb,

Thanks for the response. I’ll try to demonstrate further what I am doing. I am setting up my character like so:

local leftBody = { 0,-15, 50,-15, 50,-5, 0,-5 }  
local rightBody = { -50,-15, 0,-15, 0,-5, -50,-5 }  
local frontBody = { 0,-37, 37,-10, 23,34, -23,34, -37,-10 }  
  
physics.addBody( character, "static",   
 { density=1.0, bounce=0.4, friction=0.15, shape=leftBody },  
 { density=1.0, bounce=0.4, friction=0.15, shape=rightBody },  
 { density=1.0, bounce=0.4, friction=0.15, shape=frontBody }  
)  

Then using a local collision detection function I am checking the direction the character is facing ( where the direction is a separate property that I defined for the character ) and based on the direction he’s facing, I want that to determine which of the above bodies are active.

local onLocalCollision = function( self, event )  
 if event.force \> 1 and not self.isHit then  
 --print("collision with " .. event.otherElement) if event.other.myName == "character" and character.direction == "L" then  
 if event.otherElement == "2" then  
 --event.other.isBodyActive = false elseif event.otherElement == "3" then  
 event.other.isBodyActive = false  
 else  
 event.other.isBodyActive = true  
 end  
 elseif event.other.myName == "character" and character.direction == "R" then  
 --more logic...  
 end  
 end  
end  

Ignoring the fact that I should really be applying a sort of delay before attempting to change the property of objects straight after collision (which I will handle after), I am just looking to ensure that when the character is facing left (“L”) that the right and front body objects aren’t active, etc…

The flag approach you suggested will work fine except that I need to actually make the bodies inactive otherwise objects still bounce off of them - I want it to be such that when they’re inactive it is like they’re not even there.

Kind Regards,
Rich [import]uid: 125022 topic_id: 34008 reply_id: 135287[/import]

Huh ok. Can you set the individual parts of the bodies to sensors? You talk about the sensor property in your first post but I don’t really understand what the outcome is.

As a note, sensors will still send collision events but will not interact with (AKA cause other objects to bounce off). If they are set as sensors you will still probably need to check if they are active in your collision listener. [import]uid: 181948 topic_id: 34008 reply_id: 135289[/import]

When checking the collisions, do you have checks for each object the body collides with or do you just check the body?

If you just have one listener that checks the body, you could set up some flags (booleans) and ignore the collision event when does happens:

[lua]local partOneIsActive = true
local partTwoIsActive = false
local partThreeIsActive = true[/lua]

Then, in the collision listener function:
[lua]if (event.element1 == 1 ) and (not partOneIsActive) then return false end
if (event.element1 == 2 ) and (not partTwoIsActive) then return false end
if (event.element1 == 3 ) and (not partThreeIsActive) then return false end[/lua]

I’ve never dealt with multi-body collisions before so I don’t know if this will work exactly as written, but it should be close to what you need. The collision events still fire but they are ignored.

just don’t forget to set the flags when you make parts of the body active/inactive.

-Treb [import]uid: 181948 topic_id: 34008 reply_id: 135283[/import]

Hi Treb,

Thanks for the response. I’ll try to demonstrate further what I am doing. I am setting up my character like so:

local leftBody = { 0,-15, 50,-15, 50,-5, 0,-5 }  
local rightBody = { -50,-15, 0,-15, 0,-5, -50,-5 }  
local frontBody = { 0,-37, 37,-10, 23,34, -23,34, -37,-10 }  
  
physics.addBody( character, "static",   
 { density=1.0, bounce=0.4, friction=0.15, shape=leftBody },  
 { density=1.0, bounce=0.4, friction=0.15, shape=rightBody },  
 { density=1.0, bounce=0.4, friction=0.15, shape=frontBody }  
)  

Then using a local collision detection function I am checking the direction the character is facing ( where the direction is a separate property that I defined for the character ) and based on the direction he’s facing, I want that to determine which of the above bodies are active.

local onLocalCollision = function( self, event )  
 if event.force \> 1 and not self.isHit then  
 --print("collision with " .. event.otherElement) if event.other.myName == "character" and character.direction == "L" then  
 if event.otherElement == "2" then  
 --event.other.isBodyActive = false elseif event.otherElement == "3" then  
 event.other.isBodyActive = false  
 else  
 event.other.isBodyActive = true  
 end  
 elseif event.other.myName == "character" and character.direction == "R" then  
 --more logic...  
 end  
 end  
end  

Ignoring the fact that I should really be applying a sort of delay before attempting to change the property of objects straight after collision (which I will handle after), I am just looking to ensure that when the character is facing left (“L”) that the right and front body objects aren’t active, etc…

The flag approach you suggested will work fine except that I need to actually make the bodies inactive otherwise objects still bounce off of them - I want it to be such that when they’re inactive it is like they’re not even there.

Kind Regards,
Rich [import]uid: 125022 topic_id: 34008 reply_id: 135287[/import]

Huh ok. Can you set the individual parts of the bodies to sensors? You talk about the sensor property in your first post but I don’t really understand what the outcome is.

As a note, sensors will still send collision events but will not interact with (AKA cause other objects to bounce off). If they are set as sensors you will still probably need to check if they are active in your collision listener. [import]uid: 181948 topic_id: 34008 reply_id: 135289[/import]