CraftStudio Wiki
CraftStudio Wiki


CraftStudio doesn't have a built-in physics engine yet, but when it does (in the coming months), collisions will be much easier to deal with. For now, you'll need to work with either rays or map block tests to create some collision system of your own.

This tutorial is just a little intro to show how to handle collisions with ray casting.

Anatomy and creation of a ray[]

Rays are the combination of a position in space (a vector composed of X, Y and Z) and a direction (a normalized vector, that is, a vector of length 1 which points in a particular direction).

To create a new ray pointing forward at a certain position, you do:

local myRay = Ray:New( Vector3:New( 5, 30, 1 ), Vector3:Forward() )

You could create a ray at your current game object's position with:

local myRay = Ray:New( self.gameObject.transform:GetPosition(), Vector3:Forward() )

Now, Vector3:Forward() returns the global (or "absolute") forward position, so it always points in the same direction no matter where our object points. Maybe we want to make a ray that points in the same direction as our object? For that, we'll need to transform (aka. rotate) the forward vector by our game object's orientation. So, we end up with this:

local position = self.gameObject.transform:GetPosition()


local orientation = self.gameObject.transform:GetOrientation()


local myRay: Ray:New( position, Vector3.Transform( Vector3:Forward(), orientation ) )

Test collisions with map[]

Now once you have a ray, you can test for hits with a model renderer or a map renderer like so:

local someObjectWithAMapRenderer = CraftStudio.FindGameObject( "Some map object in my scene" )


local theMapRenderer = someObjectWithAMapRenderer:GetComponent( "MapRenderer" )


local distance = myRay:IntersectsMapRenderer( theMapRenderer )

Now we've got the distance from our ray to our map renderer stored in a variable named "distance". It might be "nil" (which is Lua-lingo for "nothing") if the ray didn't hit the map. So, we could test it like so:

if distance ~= nil and distance < 0.5 then

     print( "Boom! We hit the map!" )

end

This is pretty much the code used in Porté par le Vent to detect when the plane hits the map.

Test collisions with objects[]

As you can see, it's kind of involved and we've only just scratched the surface of collision handling. What you'd want to do next is test for collisions with other objects with model renderers. You could have all your collidable objects as children of a root object called "Scenery" for instance, and then iterate over them:

local allCollidables = CraftStudio.FindGameObject( "Scenery" ):GetChildren()


for i = 1,#allCollidables do

    local collidable = allCollidables[i]

    local distance = myRay:IntersectsModelRenderer( collidable:GetComponent( "ModelRenderer" ) )

    if distance ~= nil and distance < 0.5 then
         print( "We hit an object named " .. collidable:GetName() )
    end

end

Hope this helps get you started! You can look at the code for various existing projects to get a feel of how to use all this better (feel free to ask more questions of course).