Quad

Quad extends Object, adding functions and properties to it.

A Quad is an object which model has four vertices, forming a square. It can be filled with a color or an image.

It has many uses in creating UI, building a 2D world, or creating special effects.

Code examples of Quad's features can be found in the following worlds,
- Quad Image Test
- Quad 9-Slice Test
- Quad Cutout Test
- Quad Gradient Test
- Quad Transparency Test

Constructors

Quad ( )

Creates a Quad with default properties.

local q = Quad()

-- set quad properties
q.Height = 2
q.Color = Color(1.0, 1.0, 0.5)

-- use it as a normal object in the scene
q:SetParent(World)
q.Position = { x, y, z }

Functions

Inherited from Object

Hide

nil Load ( string itemName, function callback, table config optional )

Loads the given item asynchronously and calls the callback once done. The parameter itemName follows the usual naming convention user.item.

This is a function of the global Quad, to be called as Object:Load(itemName, callback, config).

The config table options are as follows,
- mutable allows to create the item shapes as MutableShape instead of Shape. Default false.
- bakedLight allows to generate baked lighting for the item shapes. Default false.

nil AddChild ( Object child, boolean keepWorld optional )

Adds given Object as a child. Object extensions like Shape or MutableShape are naturally accepted too.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

local o = Object()
local myShape = Shape(Items.someuser.someitem)
o:AddChild(myShape)
nil RemoveChild ( Object child, boolean keepWorld optional )

Unsets parent/child relationship with child parameter. The child ends up being deleted if it has no other references.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveChild(someChildObject)
nil RemoveChildren ( boolean keepWorld optional )

Unsets parent/child relationship with all children. Individual children end up being deleted if they have no other references.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveChildren()
nil GetChild ( integer index )

Get child Object at index.

if o.ChildrenCount > 0 then
  print(o:GetChild(1)) -- prints first child
end

Get Quad's parent.

print(myObject:GetParent())
nil SetParent ( Object parent, boolean keepWorld optional )

Sets parent/child relationship with parent parameter. nil can be used to remove the Object from its parent.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

It's also a good practice to set child/parent relationships before setting positions.

local o = Object()
o:SetParent(Map) -- o is now a child of the map
-- (Map is an extension of Object)
nil RemoveFromParent ( boolean keepWorld optional )

Removes the Quad from its parent. Doesn't do anything if the Quad has no parent.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveFromParent()

Converts a local position to world coordinate system.

local p = Number3(1, 2, 3)
local pInWorldCoords = myObject:PositionLocalToWorld(p)

Converts a world position to local coordinate system.

local p = Number3(1, 2, 3)
local pInLocalCoords = myObject:PositionWorldToLocal(p)

Rotates the Quad in its own coordinates system.

o = Object()
-- rotate with provided Euler angle
o:RotateLocal({0, 0, math.pi / 2.0})

-- rotate along specified axis
o:RotateLocal(o.Forward, math.pi / 2.0)

Rotate the Quad in the World coordinates system.

o = Object()
-- rotate with provided Euler angles
o:RotateWorld({0, 0, math.pi / 2.0})

-- rotate along specified axis
o:RotateWorld(o.Forward, math.pi / 2.0)
-- same as o:RotateLocal({0, 0, 1}, math.pi / 2.0)

Converts a rotation from local to world relative to this object.

Converts a rotation from world to local relative to this object.

Returns true if the two Objects may collide with each other.

nil ApplyForce ( Object self, Number3 value )

Apply a force to Object, taking into account its Mass.

Resets to Quad's original collision box. For example, Player and Shape objects will revert to fitting their model bounding box.

Properties

Anchor of the quad, { 0.0, 0.0 } by default, which corresponds to the lower left corner.

For example, { 0.5, 0.0 } would correspond to the middle of the bottom edge of the quad.

Color of the quad, white by default. The color of each of the four vertices can also be set individually by passing a table of up to four colors.

Quad.Color also features a helper to set up gradients: { gradient="H"/"V" or "X"/"Y", from=color1, to=color2 }.

It also gives the option to opt-in to alpha-blending, instead of the default unordered transparency. Opt-in by adding the option: { ..., alpha=true }. Using this option turns OFF some optimizations and is generally slower than default transparency, but more accurate.

An example of quad gradients can be seen in the world Quad Gradient Test.

-- quad color accepts a table of up to four colors
q.Color = { vcolor1, vcolor2, vcolor3, vcolor4 }

-- this sets all colors at once
q.Color = Color.Blue

-- use helper for a horizontal gradient
q.Color = { gradient="H", from=Color.Blue, to=Color.Red }

-- make the quad use default transparency if any given color has alpha < 255
local c = Color(255, 0, 0, 120)
q.Color = c
q.Color = { vcolor1, vcolor2, vcolor3, c }

-- opt-in to alpha-blending, instead of default transparency, gives more accurate results but is slower
q.Color = { c, alpha=true }
q.Color = { vcolor1, vcolor2, vcolor3, c, alpha=true }

Height of the quad model, 1.0 by default.

Assign with a compatible image Data to display it on the quad, with default settings. Set it to false or nil to clear it.

When getting this value, it returns true if the quad is currently textured.

Alternatively, you can assign a table to have full control over its options: { data, 9slice, 9sliceScale, alpha, cutout },
- data (Data) is the image data you would normally set.
- 9slice (boolean or Number2) can be set to true to activate 9-slice with default UV slice (0.5, 0.5), it can also be set to a custom UV slice directly.
- 9sliceScale (number) is the scale of the 9-slice corners. It can be relevant to use points scaling here, with Screen.Density.
- alpha (boolean) enables alpha-blending transparency, default false. Set this to true if you want Cubzh to use the image alpha.
- cutout (boolean or number) can be set to true to enable alpha cutout with default alpha 0.0, or set to a custom cutout directly. This means all texels from the image with alpha value lower or equal to the cutout value will be ignored. This value is typically redundant with alpha, and unless you have a specific use-case in mind, you should use one or the other. Animating the cutout value is a great way of creating interesting visual effects.

Note: you can also enable transparency on a textured quad by giving it an alpha value less than 255, eg. quad.Color.A = 254. This however will have it be rendered in an unordered transparency pass.

Code examples of Quad.Image's options can be found in the following worlds,
- Quad Image Test
- Quad 9-Slice Test
- Quad Cutout Test

-- make an alpha-blended textured quad
q.Image = { data=d, alpha=true }

-- enable 9-slice with default parameters
q.Image = { data=d, slice9=true }

-- enable 9-slice with custom UV slice, default slice is { 0.5, 0.5 }
q.Image = { data=d, slice9={ 0.25, 0.5 } }

-- enable 9-slice with custom borders scale, default is 1.0
q.Image = { data=d, slice9Scale=2.0 }

-- can be combined
q.Image = { data=d, slice9={ 0.6, 0.0 }, slice9Scale=0.8, alpha=true }

-- make an opaque cutout quad with default value
q.Image = { data=d, cutout=true }

-- make an opaque cutout quad with custom value
q.Image = { data=d, cutout=0.2 }

If true, both sides of the quad are rendered, true by default.

Setting this to false can be done as an optimization when using quads for UI or 2D games.

Note: currently, quads back faces are not lit.

Activates masking for this quad. Any children of a quad mask will only be visible within the quad's area on screen.

Nested masks are supported to a maximum depth of 7. Up to 31 individual masks can be active at a time, nested masks do not count towards this limit.

Whether or not the Quad should ignore scene lighting, false by default.

Integer or table of integers between 1 and 12. Cameras only render quads corresponding to their layers, and lights only affect quads in matching layers.

Offset of the texture on this quad. Only has effect if the quad is textured by setting its Quad.Image property.

This can be used to select an area of the texture to display, or to create scrolling effects.

Whether or not the quad should be affected by light shadow casters in matching layers.

Returns the size of the quad model. Equivalent to Number2(quad.Width, quad.Height).

Tiling of the texture on this quad. Only has effect if the quad is textured by setting its Quad.Image property.

This can be used to repeat a pattern over the quad's surface. Especially useful when combined with a seamless image, to create a continuously textured surface.

Width of the quad model, 1.0 by default.

Inherited from Object

Hide

Quad's constant acceleration in world coordinates per second squared.

⚠️ Acceleration will only affect Quad's position while Quad.Physics is true.

-- Acceleration can be used to compensate gravity: 
myObject.Acceleration = -Config.ConstantAcceleration
-- myObject's acceleration is now the invert of 
-- Config.ConstantAcceleration, cancelling it.

Collision groups the Quad belongs to.

⚠️ It doesn't mean the Quad will collide with other Objects in these groups.

If the Quad belongs to group number 3 for example, it means all Objects that have group number 3 in their Object.CollidesWithGroups property will collide with it.

By default:
- Objects collide with the Map and other Objects
- Players collide with the Map only

That can all be configured differently depening on your needs.

local object1 = Object()
local object2 = Object()
-- It's not mandatory to set Physics to true
-- An object with Physics set to false contributes to the
-- physics simulation as a static item (can't be moved)
object1.Physics = true
object2.Physics = true

-- making sure 2 objects collide with each other
-- NOTE: by default:
-- Map.CollisionGroups == {1},
-- Player.CollisionGroups == {2},
-- Object.CollisionGroups == {3}
object1.CollisionGroups = {5}
object2.CollisionGroups = {5}
object1.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5
object2.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5

-- would also work this way if you don't 
-- remember Map's group (which can be changed too by the way)
object1.CollidesWithGroups = Map.CollisionGroups + {5}

-- making an object collides with the Map and Players
local object = Object()
object.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

-- for Player (local player) to collide with other players and the Map
Player.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

Collision groups the Quad collides with.

By default:
- Objects collide with the Map and other Objects
- Players collide with the Map and the Objects

That can all be configured differently depending on your needs.

local object = Object()

-- It's not mandatory to change Physics value.
-- (default value is PhysicsMode.Static)
-- An object with Physics set to PhysicsMode.Static contributes 
-- to the physics simulation as a static item (can't be moved)
object.Physics = PhysicsMode.Dynamic

-- making an object collide with the Map and Players
object.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

-- for an Object to collide with other objects only
-- (won't collide with the map)
object.CollidesWithGroups = object.CollisionGroups

-- for Player (local player) to collide with other players and the Map
Player.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

-- making sure 2 objects collide with each others
-- NOTE: by default:
-- Map.CollisionGroups == {1},
-- Player.CollisionGroups == {2},
-- Object.CollisionGroups == {3}
local object1 = Object()
local object2 = Object()
object1.CollisionGroups = {5}
object2.CollisionGroups = {5}
object1.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5
object2.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5

-- would also work this way if you don't 
-- remember Map's group (which can be changed too by the way)
object1.CollidesWithGroups = Map.CollisionGroups + {5}

Sets the simulation mode for this object, it can be one of the following:
- PhysicsMode.Disabled: excluded from all physics features.
- PhysicsMode.Trigger: Quad's collision box is available for casts and collision callbacks, and is passed through by other dynamic objects.
- PhysicsMode.TriggerPerBlock: if Quad is a Shape, its model blocks are available for casts and collision callbacks, and is passed through by other dynamic objects.
- PhysicsMode.Static: Quad's collision box is available for casts, collision callbacks, and acts as an obstacle for other dynamic objects.
- PhysicsMode.StaticPerBlock: if Quad is a Shape, its model blocks are available for casts, collision callbacks, and act as obstacles for other dynamic objects.
- PhysicsMode.Dynamic: Quad's world-aligned collision box is available for casts, collision callbacks, may act as obstacles for other dynamic objects, and is itself fully simulated.

By default, objects are set to PhysicsMode.Static.

You may use Dev.DisplayColliders to visualize each object's collision settings.

⚠️ When set to PhysicsMode.Disabled, Quad.Velocity & Quad.Motion are set to {0,0,0}.

nil by default. Can be set to a function that will be triggered when this object begins a collision with another object.

The function is called with 3 parameters:
- the object the callback was set for,
- the other actor in the collision,
- the world normal of the hit surface.

Note: it's not necessary to use all 3 parameters.

object.OnCollisionBegin = function(self, other, normal)
  print("collision began between", self, " and ", other, " with world normal ", normal)
end

nil by default. Can be set to a function that will be triggered every frame where this object remains in contact with another object.

Like OnCollisionBegin, this function has 3 arguments: self, other, normal.

nil by default. Can be set to a function that will be triggered when the Quad ends colliding with another Object.

The function is called with 2 parameters: the object the callback was set for and the other actor in the collision.

object.OnCollisionEnd = function(self, other)
  print("collision ended between", self, "and", other)
end

Position of the Quad in the world.

local o = Object()
-- places the object where the local player is
o.Position = Player.Position
boolean IsOnGround read-only

true when the Quad is not falling.

⚠️ IsOnGround only makes sense when Quad.Physics is true.

Can be set to true for the Quad to be hidden recursively, meaning Quad and all of its children are hidden.

Nothing else changes, the Quad remains in the scene and it keeps being affected by the simulation (collisions, etc.).

Can be set to true for the Quad to be hidden individually.

Nothing else changes, the Quad remains in the scene and it keeps being affected by the simulation (collisions, etc.).

Size in world units of the shadow cookie projected under the Quad, default is 0.0 (disabled).
The shadow cookie, also called blob shadow, is a square texture acting as a cheap alternative to projected shadows.

If this value is strictly positive, shadow cookies will be displayed when:
- the scene has no light source,
- the scene has light sources, but they are disabled because the client is using lower quality settings

Shadow cookies can be used as a fallback to your scene shadows for players with low quality settings, of course, you can also use them instead of shadows as a design choice.

Local position of the Quad relative to its parent.

All of Quad's ancestors local transformations are combined to obtain the Quad "world position" (Object.Position), the Object's final position.

Rotation of the Quad in the world (as seen on screen).

While it usually works for simple operations (like Rotation.X = Rotation.X + someAngle), we advise you to use Number3.Rotate to rotate an object around X, Y & Z axis.

You can also set unit vectors like Quad.Up, Quad.Right or Quad.Forward to orient your object.

local o = Object()
o.Rotation = {0, math.pi, 0}
-- o revolved half a turn on Y axis

-- another way to rotate the object:
o.Forward:Rotate({0, 0, math.pi / 2})
o.Forward = Camera.Forward

Tick is a function executed ~30 times per second when set (nil by default). Provides the Quad and elapsed time in seconds as parameters.

-- executed ~30 times per second on each user device
myObject.Tick = function(object, dt)
  print("elapsed:", dt, "seconds")
end

Local rotation of the Quad relative to its parent.

All of Quad's ancestors local transformations are combined to obtain the "world rotation" (Object.Rotation), the Object's final rotation.

Velocity of the Quad in world coordinates per second.

⚠️ Velocity will only affect Quad's position while Quad.Physics is true. Whenever it is set to false, Velocity is set to {0,0,0}.

-- makes myObject jump:
myObject.Velocity.Y = 100

Be aware, this Motion property is a hack regarding laws of physics. (sorry Isaac)

But it's very practical to move objects without worrying about forces at play.

This is what's being used by default when you're moving around with your avatar (see Client.DirectionalPad). It's the reason why you can stop moving horizontally while in the air.

Basically, Motion is an instantaneous displacement that contributes to moving Quad every frame, without changing Quad.Velocity directly.

Motion is expressed in world coordinates per second.

⚠️ Motion will only affect Quad's position while Quad.Physics is true. Whenever it is set to false, Motion is set to {0,0,0}.

local speed = 10
myObject.Motion = Camera.Forward * speed
-- myObject will move in the same direction the camera is currently facing.
-- If the Camera rotates after this, it won't change where myObject is heading.

Scale of the Object, in its parent.

Nested Object local scales are combined to obtain the "world scale" (Object.LossyScale), the Object's final scale.

myObject.LocalScale = 2 -- the Object is now 2 times bigger
topLevelObject.LocalScale = 2
local o = Object()
o.LocalScale = 0.5
topLevelObject:AddChild(o) -- o becomes a child of topLevelObject
-- o ends up being displayed with a scale of 1
number LossyScale read-only

Convenience property that attempts to match the actual world scale as much as it can. Note that Objects that have multiple levels of nested rotations and scales will return a skewed lossy scale.

The mass of the Object determines how much a given force can move it and whether or not another object can be pushed by it. It cannot be zero, a neutral mass is a mass of 1.

The combined friction of 2 Objects in contact represents how much the moving Object will be able to slide along the colliding Object.

It is a rate between 0 (full slide, no friction) and 1 (maximum friction). Values equal to or lower than 0 will keep or increase momentum, like sliding on ice. Values higher than 1 means a faster stop, up to a value of 2 to ensure a full stop on contact regardless of the colliding Object's own friction.

[Object.Friction] can be set per-face by providing a table with any combination of the following keys : right, left, front, back, top, bottom, other.
For example, to set the friction on the bottom face of an object's collider to 0 and 0.2 on every other faces, you could set, object.Friction = { bottom=0, other=0.2 }.

The combined bounciness of 2 Objects in contact represents how much of the moving Object's velocity is produced after being in contact with the colliding Object, it is a rate between 0 (no bounce) and 1 (100% of the velocity bounced). Values higher than 1 are allowed and will create an increasing momentum at each bounce (try at your own risk).

[Object.Bounciness] can be set per-face by providing a table with any combination of the following keys : right, left, front, back, top, bottom, other.
For example, to set the bounciness on the side faces of an object's collider to 0.2 and 0 on top and bottom faces, you could set, object.Bounciness = { top=0, bottom=0, other=0.2 }.

All Objects have a collision box that represents the space occupied in the scene with regards to collisions. For Shapes and Players, the collision box is updated with their bounding box. For Objects, it is a 1-cube by default after physics was enabled for the first time.

Returns number of child Objects.

Up is a unit vector (vector with a length of 1). It determines which direction is "up" for the Quad.

Setting it is a way to rotate the Quad.

Right is a unit vector (vector with a length of 1). It determines which direction is "right" for the Quad.

Setting it is a way to rotate the Quad.

Forward is a unit vector (vector with a length of 1). It determines which direction is "forward" for the Quad.

Setting it is a way to rotate the Quad.

Left is a unit vector (vector with a length of 1). It determines which direction is "left" for the Quad.

Setting it is a way to rotate the Quad.

Down is a unit vector (vector with a length of 1). It determines which direction is "down" for the Quad.

Setting it is a way to rotate the Quad.

Backward is a unit vector (vector with a length of 1). It determines which direction is "backward" for the Quad.

Setting it is a way to rotate the Quad.