Physics Bodies


The physics world is based on the interactions of rigid bodies. These physical bodies can be bound to Corona display objects in a one-to-one relationship, and Corona will automatically handle all position updates and other synchronization tasks.

In fact, our goal is that you should be able to consider the physical bodies as literally part of the visible display objects. Therefore, the body constructor physics.addBody does not return a new object, but instead “extends” an existing display object with physical properties.

Therefore, standard object read/write attributes like x, y and rotation should continue to work normally on a physical body, although if the bodyType is “dynamic”, the physics engine may “fight back” against your attempts to move the object manually, since the target object will be under the constant effect of gravity and other forces.

The “DragPlatforms” sample code shows one method for changing body types to “kinematic” during dragging, which temporarily removes them from the influence of external forces. In contrast, the "DebugDraw" sample shows a method for dragging objects using "touch joints" that does not remove them from external forces. The second method is probably more useful in physics-based games, but you can compare the two examples to see the difference between "kinematic" and "dynamic" object behavior.

A display object that has physical properties can be deleted in the normal way, using object:removeSelf(). It will be automatically removed from both the visible screen and the physical simulation. Note: You can remove the Physics properties of an object using "physics.removeBody"


When you turn a display object into a physics object, the Physics engine owns the object and has its own rules about the object. Physics assumes the reference point of the object is the center of the object so object:setReferencePoint() may change the reference point from Corona's Display Object point of view but not for the Physics engine. This affects collisions and how other physics bodies interact.

The same applies for scaling and rotating the object. You can scale the object up or down and rotate it but the Physics engine still sees the object as it was before the changes.

You can see how the Physics engine view the object with physics.setDrawMode("debug").

Simple body construction


This allows you to turn any Corona display object into a simulated physical object with one line of code, including the assignment of physical properties.

Physical bodies have three main physical properties:

  • density is multiplied by the area of the body’s shape to determine its mass. This parameter is based on a standard value of 1.0 for water, so materials that are lighter than water (such as wood) have a density below 1.0, and heavier materials (such as stone) have a density greater than 1.0. However, feel free to set density values to whatever feels right for your game, since overall object behavior will also depend on your gravity and pixels-to-meter scale settings (see previous section). The default value is 1.0.
  • friction may be any non-negative value; a value of 0 means no friction and 1.0 means fairly strong friction. The default value is 0.3.
  • bounce is the Box2d property known internally as “restitution”, and determines how much of an object’s velocity is returned after a collision. Values greater than 0.3 are fairly “bouncy”, and an object with a bounce value of 1.0 will rebound forever (i.e., if dropped to the ground, it will bounce back up to roughly the height from which it was dropped). Bounce values higher than 1.0 are valid, but will cause strange behavior: objects will literally gain velocity with each collision until they fly off into space. The default value is 0.2, which is slightly bouncy.

You may find that an object with a bounce set to exactly 1.0 will rebound somewhat higher than its original height, due to numerical approximations in Box2D. Bounce values slightly below 1.0, possibly combined with some linear damping, may be used for a closer simulation of "same height" behavior over short periods of time. Over long periods of time, it may be difficult to avoid runaway or decaying bounce.

Default (rectangular) bodies

By default, this constructor assumes that the physical object is rectangular, with collision boundaries that automatically snap to the edges of the associated image or vector object. This works well for crates, platforms, large ground bodies, and other simple rectangular sprites. All parameters in the table are optional, and all default to reasonable values if not provided.

local crate = display.newImage( "crate.png", 100, 200 )
physics.addBody( crate, { density = 1.0, friction = 0.3, bounce = 0.2 } )

Note that the table of physical attributes can be declared externally and then used multiple times:

local crate1 = display.newImage( "crate.png", 100, 200 )
local crate2 = display.newImage( "crate.png", 180, 280 )
local crateMaterial = { density = 1.0, friction = 0.3, bounce = 0.2 }
physics.addBody( crate1, crateMaterial )
physics.addBody( crate2, crateMaterial )

Also note that this default constructor assumes that your physics object has the same rectangular boundaries as your display object. This is very convenient in many cases, but in other cases may not be what you want. For example, a vector line drawn diagonally using display.newLine() is actually rendered as a rectangular object, since it creates a rectangular area of OpenGL texture (which would be mostly transparent, in this case).

If you do not want your physics body to match this bounding rectangle, you should define more specific shape data using either the circular radius property or the array of polygon coordinates discussed below.

When in doubt, you can use physics.setDrawMode() to get a "behind the scenes" view of what the physics engine is actually doing, including the collision boundaries for your physics bodies.

Circular bodies

Circular bodies require an additional radius parameter. This works well for balls, rocks, and other objects that can be treated as perfectly round when calculating collisions. If the visible sprite is round but irregular (say, a boulder or an egg), you may wish to set this radius slightly smaller than the physical image size.

Note that there is no such thing as a non-circular oval in Box2D collision geometry, since circular bodies exist as a special case. To make an oval body, you would instead lay out a series of specific boundary points to outline the shape as a polygon (see below).

local ball = display.newImage( "ball.png", 100, 200 )
physics.addBody( ball, { density = 1.0, friction = 0.3, bounce = 0.2, radius = 25 } )

Polygon bodies

General polygonal bodies that don’t fall into the above two special cases are generated with a “shape” parameter, which is used to pass a Lua table of (x,y) coordinate points that outline the collision boundaries. These coordinates are specified relative to the display object: by default, Corona sets the origin of a display object at the center of the corresponding image file (or vector object). So (0,0) corresponds to the center of the object. (-20,-10) defines a point 20 pixels to the left of center and 10 pixels above the center.

For example, to define a rectangular shape 20 pixels high and 40 pixels wide, with its origin at its center, the following shape definition would be used:

squareShape = { -20,-10, 20,-10, 20,10, -20,10 }

The maximum number of points (and therefore edges) allowed per collision shape is eight. Once defined, a shape definition can be re-used multiple times.

Note that these polygon coordinates must be defined in clockwise order, and the resulting shape must be convex-only. Coordinate sets that violate these two rules may appear to work, but their objects will behave oddly in collisions: for example, they may become stuck to other objects. (Concave physical objects must be assembled from multiple elements attached to the same body; see "Complex body construction" below.)

Here are two valid examples:

local triangle = display.newImage("triangle.png")
triangle.x = 200
triangle.y = 150
triangleShape = { 0,-35, 37,30, -37,30 }
physics.addBody( triangle, { density=1.6, friction=0.5, bounce=0.2, shape=triangleShape } )
local pentagon = display.newImage("pentagon.png")
pentagon.x = 200
pentagon.y = 50
pentagonShape = { 0,-37, 37,-10, 23,34, -23,34, -37,-10 }
physics.addBody( pentagon, { density=3.0, friction=0.8, bounce=0.3, shape=pentagonShape } )

For examples of polygonal body specifications, see “ShapeTumbler” and the bumper objects in “SimplePool”.

bodyType Constructor

Here are two ways to specify the bodyType when adding a Physics body.

physics.addBody( triangle, "static", { density=1.6, friction=0.5, bounce=0.2, shape=triangleShape } )

Alternatively, you can construct the body and then set its type attribute:

physics.addBody( triangle, { density=1.6, friction=0.5, bounce=0.2, shape=triangleShape } )
triangle.bodyType = "static"

Possible bodyTypes are “static”, “dynamic” and “kinematic”, and the default type is “dynamic” if no value is specified.

In general, you can allow moving objects to default to “dynamic”, and specify “static” for objects (like walls or the ground) that shouldn’t move or fall under gravity.

Complex body construction

The above examples assume a body with only one element. However, it is also possible to construct a body from multiple elements. In this context, each body element is specified as a separate polygon shape with its own physical properties.

For example, to model a pencil, you would probably want to define the eraser end as a separate body element with a much higher “bounce” value than the rest of the pencil.

Also, since collision polygons in Box2D must be convex, any game object with a concave shape must be constructed by appending multiple body elements. For example, to model a car, you would use a body with two or more body elements, since the shape of a car includes concave angles, such as the angle where the windshield meets the hood of the car.

The constructor for a complex body is the same as the simple polygon body constructor, except with more than one body element listed:

physics.addBody( displayObject, [bodyType,] bodyElement1, [bodyElement2, ...] )

Each body element may have its own physical properties, along with a shape definition for its collision boundaries. For example:

local car = display.newImage("big_red_car.png")
roofShape = { -20,-10, 20,-10, 20,10, -20,10 }
hoodShape = { 0,-35, 37,30, -37,30 }
trunkShape = { 0,-37, 37,-10, 23,34, -23,34, -37,-10 }
physics.addBody( car, "dynamic",
  { density=3.0, friction=0.5, bounce=0.2, shape=roofShape },
  { density=6.0, friction=0.6, bounce=0.4, shape=hoodShape },
  { density=4.0, friction=0.5, bounce=0.4, shape=trunkShape }

(These shape definitions are for example only, and probably would not make a very good car shape.)

As in the simpler cases, the bodyType attribute is optional and will default to “dynamic” if not specified.


Any body (or element of a multi-element body) can be turned into a “sensor”. Sensors do not physically interact with other bodies, but produce collision events when other bodies pass through them. For example, the pockets on a pool table might be implemented as sensors.

Because the simplest Corona body constructors are based on visible display objects, the easiest way to implement an invisible sensor region is to create a display object and then make it invisible:

local rect = display.newRect( 50, 50, 100, 100 )
rect:setFillColor( 255, 255, 255, 100 )
rect.isVisible = false  -- optional
physics.addBody( rect, { isSensor = true } )

The visible object can be used for game debugging, and then the isVisible property can be set to false once debugging is complete. In the above example, the initial display object is a translucent vector rectangle using the Corona drawing API.

Destroying bodies

Physics bodies can be destroyed like any other display objects:

-- or --
myBody.parent:remove( myBody )

The first method above is recommended for simplicity, and is the same syntax used to destroy physics joints (which do not have parents, since they are invisible and not part of the display hierarchy).

When you destroy bodies or joints, Corona will automatically handle the process of holding onto the corresponding Box2D objects until the end of the current physics world step, and then safely dispose of them.


While Box2D objects will be safely retained until the end of the current world step, their Lua references will be deleted immediately. Therefore, be careful not to accidentally delete the same Lua object more than once. This situation could occur when deleting objects involved in collisions, which can potentially have many event phases before the collision is fully resolved. The solution is simple:

local function onCollision( self, event )
        if ( event.phase == "began" ) then
                -- Check if body still exists before removing!
                if ( crate1 ) then
                        crate1 = nil

Body properties

Many of the native Box2D setter/getter methods have been reduced to simpler dot properties on the display object. The following examples assume that a body myBody has been created using one of the above constructor methods.


A boolean for the current awake state. By default, all bodies automatically “go to sleep” when nothing interacts with them for a couple of seconds, and then they stop being simulated until something (e.g., a collision) wakes them up. This property can either fetch their current state or forcibly wake them up.

myBody.isAwake = true
local state = myBody.isAwake


A boolean for the current active state. Inactive bodies are not destroyed, but they are removed from the simulation and cease to interact with other bodies.

myBody.isBodyActive = true
local state = myBody.isBodyActive


A boolean for whether the body should be treated as a “bullet”. Bullets are subject to continuous collision detection, rather than periodic collision detection at world timesteps. This is more computationally expensive, but it prevents fast-moving objects from passing through solid barriers. The default is false.


A (write-only) boolean property that sets an internal "isSensor" property across all elements in the body. A sensor passes through other objects rather than bouncing off them, but still fires some collision events (for example, the table pockets in the "SimplePool" sample code are sensors). Because this body property acts across all body elements, it unconditionally overrides any "isSensor" settings on the elements themselves.

myBody.isSensor = true


A boolean for whether the body is ever allowed to go to sleep. Keeping bodies awake has a larger overhead, and is often not required, because collisions with other bodies will automatically wake them up. However, forcing awakeness is useful in cases such as the tilt-gravity case (since sleeping bodies do not respond to changes in global gravity). The default is true.

myBody.isSleepingAllowed = true
local state = myBody.isSleepingAllowed


A boolean for whether the rotation of the body should be locked, even if the body is under load or subjected to off-center forces. The default is false.

myBody.isFixedRotation = true
local state = myBody.isFixedRotation


The numerical value of the current angular (rotational) velocity, in degrees per second.

myBody.angularVelocity = 50
local v = myBody.angularVelocity


The numerical value for how much the body's linear motion is damped. The default is zero.

myBody.linearDamping = 5
local d = myBody.linearDamping


The numerical value for how much the body's rotation should be damped. The default is zero.

myBody.angularDamping = 5
local d = myBody.angularDamping


A string value for the type of physical body being simulated. Possible values are "static", "dynamic" and "kinematic".

  • static bodies don't move, and don't interact with each other; examples of static objects would include the ground, or the walls of a pinball machine.
  • dynamic bodies are affected by gravity and collisions with the other body types.
  • kinematic objects are like static bodies, but they can be moved and are affected by forces but not by gravity, so you should generally set draggable objects to “kinematic”, at least for the duration of the drag event.

The default body type is "dynamic".

myBody.bodyType = "kinematic"
local currentType = myBody.bodyType

Body methods

The following examples assume that a body myBody has been created using one of the above constructor methods.


A function that accepts x,y components for the body's linear velocity, in pixels per second.

myBody:setLinearVelocity( 2, 4 )


A function that returns x,y components for the body's linear velocity, in pixels per second.

vx, vy = myBody:getLinearVelocity()


A function that accepts x,y components of a linear force, applied at a given point with x,y world coordinates. If the target point is the body's center of mass, it will tend to push the body in a straight line; if the target is offset from the body's center of mass, the body will spin about its center of mass.

For symmetrical objects, the center of mass and the center of the object will have the same position: (object.x, object.y). Also note that the amount of force may need to be fairly high to move heavy objects.

myBody:applyForce( 500, 2000, myBody.x, myBody.y )


A function that accepts a numerical value for applied rotational force. The body will rotate about its center of mass.

myBody:applyTorque( 100 )


Like applyForce, except that an impulse is a single, momentary jolt.

myBody:applyLinearImpulse( 600, 200, myBody.x, myBody.y )


Like applyTorque, except that an angular impulse is a single, momentary jolt.

myBody:applyAngularImpulse( 100 )

Force vs. Impulse?

A common question is the difference between applying "force" and "impulse" to a body. The difference is that an impulse is meant to simulate an immediate "kick" to the body, but force (and torque) is something exerted over time. Therefore, to get a realistic force simulation, you should reapply the force on every frame, perhaps for several seconds, or as long as you want the force to continue. You can use an "enterFrame" event for this purpose.


If the default mass data for the body has been overridden (TBD), this function resets it to the mass calculated from the shapes.



Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
User offline. Last seen 2 years 18 weeks ago. Offline
Joined: 4 Dec 2010

In the API reference, "an object with a bounce value of 1.0 will rebound forever (i.e., if dropped to the ground, it will bounce back up to the height from which it was dropped)", However, it is wrong in the code, SampleCode/Physics/HelloPhysics/main.lua , the crate is getting higher and higher.

User offline. Last seen 2 years 18 weeks ago. Offline
Joined: 4 Dec 2010

I have changed the following code

--physics.addBody( crate, { density=3.0, friction=0.5, bounce=0.3 } )
physics.addBody( crate, { density=3.0, friction=0.5, bounce=1.0 } )

User offline. Last seen 2 years 34 weeks ago. Offline
Joined: 12 Dec 2010

You mention the units for some of the methods, e.g. pixels/sec for linear velocity, but don't mention the units for other methods, e.g. for force and impulse. What are the units for these? I guess by default force would be in Newtons but since you're using pixels for position (& not meters), it's not clear what the units for force would be.

User offline. Last seen 3 years 14 weeks ago. Offline
Joined: 16 Sep 2009

@skafta - the units of force (and all non-distance units) remain unchanged, so the units would be Newtons, Newton-meters, etc., depending on context.

However, in virtually all cases, you're going to be applying forces that don't resemble those in the real world. You should just experiment and see what values result in the appropriate game behavior.

In general, most people end up with much larger and heavier objects than their real-world counterparts would be. For example, the balls in the "SimplePool" demo are 30 pixels in diameter, with a scale factor set to 60 pixels per meter, which means the balls are simulated objects of half a meter across -- they probably weigh several kilograms or more in the internal calculations, so the forces need to be quite large to get them to move realistically. All these values were chosen experimentally, by a trial-and-error process.

Long story short, you might as well think of the force units as an arbitrary scale and just see what works!

User offline. Last seen 2 years 18 weeks ago. Offline
Joined: 4 Dec 2010

local physics = require( "physics" )
local sky = display.newImage( "bkg_clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160; ground.y = 445
physics.addBody( ground, "static", { friction=0.5, bounce=0.3 } ) -- revised for Alpha 2
local crate = display.newImage( "crate.png" )
crate.x = 180; crate.y = -50; crate.rotation = 5
physics.addBody( crate, { density=3.0, friction=0.5, bounce=0.3 } )

The above code is copied from the official demo

The problem is when I change the bounce to 1.0, the crate will rebound higher and higher. However, it should be rebounded to the same height. How to fix it ?

User offline. Last seen 3 years 14 weeks ago. Offline
Joined: 16 Sep 2009

@yuewah - Box2D uses a lot of mathematical approximation and rounding for performance reasons. Therefore, you generally won't get a perfectly equivalent bounce height by setting bounce to 1.0.

You can probably get decent behavior with a value slightly less than 1.0, possibly combined with a bit of linear damping to keep the velocity from running away. This should work at least in the short run -- see the "CollisionFilter" sample for an example of a fairly balanced system. But over long periods of time, it's probably impossible to create a bounce that doesn't eventually escalate to infinity or decay to zero.

User offline. Last seen 2 years 18 weeks ago. Offline
Joined: 4 Dec 2010

thx, evank. The cocos2d's and orginial box2d also has the same problem.

(i.e., if dropped to the ground, it will bounce back up to the height from which it was dropped). 

I think the sentence above in the document should clarify about this.

User offline. Last seen 3 years 14 weeks ago. Offline
Joined: 16 Sep 2009

@yuewah - Done!

User offline. Last seen 3 days 1 hour ago. Offline
Joined: 2 Dec 2010


i have the same problem with leaking memory by using physics engine. i create and destroy physics bodies in a loop and the memory is leaking as well (i destroy all objects by calling obj:removeSelf() and obj = nil).

i tried to call "collectgarbage("collect")" after each "game cycle" and print the current used memory after calling this function. as a result, the memory is increasing by ~1 kB after each cycle.... from my point of view, i would say this is a bug in the physics engine.

if you have further information about this problem, or if you have a workaround, please let me know!


User offline. Last seen 2 days 16 hours ago. Offline
Joined: 2 Nov 2010

I was hoping also that would be fixed in the new release, but it seems like it wasn't.

The work around I used was to just not use physics. I move my objects around using transitions rather than physics.

User offline. Last seen 2 years 20 weeks ago. Offline
Joined: 10 Jan 2011

Are there any plans to turn non-straight / curved lines created through display.newline() into physics objects? It looks like right now this isn't possible.

User offline. Last seen 2 years 27 weeks ago. Offline
Joined: 22 Sep 2009

Yes, I am also looking for a way to draw curved lines for my game. Any help in this regard is appreciated!!

User offline. Last seen 11 hours 20 min ago. Offline
Joined: 17 Aug 2010

Would a stack of boxes, for example, with collision listeners attached (though not pre- and post- listeners, to keep noise down) continuously generate events?

Even if they didn't, would there be a physics engine overhead by simply having them stacked?

I have a platform moving up and down and the stack of crates on top (like the platform dragger sample) which need collision listeners, but I'm wondering if the engine would perform better if I could disable the collision listeners. Just not sure the best route to achieve this right now.


User offline. Last seen 11 hours 20 min ago. Offline
Joined: 17 Aug 2010

Do inActive bodies get affected by joints?

User offline. Last seen 2 years 27 weeks ago. Offline
Joined: 17 Feb 2011


I have a multi element polygon body that's only dragable by a small area where the two shapes intersect. I need the whole object to respond to the touch event, not just a tiny part of it. How would I go about doing that ?

my code:

long1Shape = { 0,0, 75,0, 75,27, 0,27 }
long2Shape = { 0,0, 27,0, 27,77, 0,77 }
boomerang = display.newImage( "boomerang.png")
boomerang.x = 170
boomerang.y = 200
physics.addBody( boomerang, "dynamic",
{ density = 1.5, bounce = 0.3, friction=0.6, shape=long1Shape},
{ density = 1.5, bounce = 0.3, friction=0.6, shape=long2Shape})
boomerang:addEventListener( "touch", startDrag )

thank you!

User offline. Last seen 11 hours 20 min ago. Offline
Joined: 17 Aug 2010

I would maybe attach an invisible object set as a sensor which is attach to the rest, with 0 density and use that object as the touch object, setting isHitTestable to true.

If not, just make every component of the multi-body object fire the same touch listener.

User offline. Last seen 18 weeks 1 day ago. Offline
Joined: 20 Jan 2011


Would the body:applyLinearImpulse allow a ball to touch a power up and speed up ?

Thank you.

User offline. Last seen 11 hours 20 min ago. Offline
Joined: 17 Aug 2010

Yes, but you might want to use applyLinearForce.

This should probably be a separate thread, though.

User offline. Last seen 2 years 37 weeks ago. Offline
Joined: 15 Jun 2011


Under production it was noticed that kinematic bodies do not respond to forces at all, not just gravity, in contrast to what is written on this page. The Box2d manual also defines kinematic objects as unresponsive to any forces:

It would be helpful if this page were edited in order to avoid leading people astray.


User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 18 Feb 2011

Tom, thanks for the quick response and fix. While researching this earlier I found several forum posts with people mixing up clockwise with counter clockwise. They got the numbers correct in most of them but had mixed up their terms. I know you can't change that but I thought I would mention it for future viewers looking around the forums.

Thanks Again

User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 18 Feb 2011

Hey Tom,
I tested this more this evening and I made an error-sorry! You guys had it right-define them clockwise but if the y value is above 0 its negative and if its below 0 its positive. I thought counter clockwise was working because I was using a square but when I moved one point it would move the wrong one. Almost as if the object was flipped. The negative positive issue messed me up because I could not find documentation of that anywhere.

User offline. Last seen 12 hours 17 min ago. Offline
Joined: 13 Jul 2010

Yes, it can be confusing because Corona defines the home screen position (0,0) at the upper top left so the shapes need to be defined in the Clockwise direction.

I forgot that the Box2D documentation assumes a different coordinate system so it requires the shape table to be defined in counter-clockwise order.

Physics assume the 0,0 of the object is in the center of the object so a -x is to the left of the object's center and -y is above (towards the top of the screen) of the object's center.

User offline. Last seen 1 year 7 weeks ago. Offline
Joined: 10 May 2011

It is stated the default value for density is 1.0, which is definitely not the case (density 1 gives way heavier objects than when density is omitted). According to Box2d documentation, the default is 0 and this seems to correspond to my own observations (don't ask me why 0 density doesn't give infinite velocities ;-)).

Edit: at least this applies for rectangular bodies on build 591 (yes somewhat old now, but I guess you guys may not have changed this and the best is probably just to change the manual).

User offline. Last seen 1 year 10 weeks ago. Offline
Joined: 3 May 2012

Above it says
"Note: You cannot remove the Physics properties of an object -- you can only remove the entire object."

That's false; there's the command "physics.removeBody()" to remove the physics body without removing the display object:

User offline. Last seen 12 hours 17 min ago. Offline
Joined: 13 Jul 2010


You're correct about physics.removeBody. That API was added recently and the documentation was never updated. I'll make the correction.


User offline. Last seen 1 year 10 weeks ago. Offline
Joined: 3 May 2012

It should be noted that circular bodies have no rolling friction. Without obstacles, a circle will keep on rolling forever.

There are various solutions:
- Using a polygon body instead.
This worked fine for me. I built a circle with 8 shapes, totalling 64 polygon points.
(Instead of entering the point coordinates manually, this can be done by calculating the points with a bit of math.)

- Using the body.angularDamping property.
This worked, but then the body will slow down its rotation velocity even in mid-air.

- Maybe use a joint and a motor to reduce the rotation velocity. Not tested.

- Maybe use body:getLinearVelocity() and body:setLinearVelocity() to set a reduced velocity each frame. Not tested.

User offline. Last seen 5 weeks 1 day ago. Offline
Joined: 31 Oct 2010

Hey, I don't think the docs are really clear on this, so I'll just say it in case it saves anyone some time...

The only type that can cause a collision is a "dynamic" type.

Maybe someone from Corona could verify that this is correct and, if so, put that in the docs.

For "static" the docs state: "static bodies don't move, and don't interact with each other;..." but I read this and think that it means you just can't apply forces on them or bounce them off of other things... and regardless, the docs don't clearly state the lack of collision detection between two kinematic bodies.