Scripting with Cog

Working with objects

self is the object your script is on. Scene.find, Scene.spawn, and the other a collision gives you are the same kind of handle, for another object. Everything below works on any of them, and the Cog API reference lists every member.

Where it is

fn on_update(delta: float) {
    self.position = self.position + Vec3.up * delta          // rise, one unit a second
    var a = self.euler_angles                                 // degrees
    self.euler_angles = Vec3(a.x, a.y + 90.0 * delta, a.z)   // and turn, 90 degrees a second
}

position is where the object is in the world, a Vec3, and rotation is which way it faces, a Rotation. euler_angles is the same rotation as angles in degrees, applied Y, then X, then Z. Each has a local_ version measured from the object’s parent: the numbers its Transform holds and the Inspector shows. For an object with no parent, the world and local ones are the same.

Each is set by assigning it: self.position = Vec3(0, 2, 0), or Scene.find("Door").local_euler_angles = Vec3(0, 90, 0) to swing a door on its hinge.

Name, id and tags

Every object has a name, a unique id and tags, and has_tag("enemy") asks whether it carries one.

Physics

An object with a Rigid Body or Character Controller has a velocity and an angular_velocity, and grounded says whether a character is standing on something.

The actions that move it belong to the component, not to self: an object without a Rigid Body has nothing to push.

var body = self.get_component("RigidBody")
body.apply_impulse(Vec3.up * 5.0)         // a kick, at once
body.apply_force(Vec3(0, 0, -20))         // a push; call it every frame to keep pushing
self.get_component("CharacterController").set_velocity(Vec3(0, 0, -6))

Components

get_component gives you a component’s properties as an object, with its actions as functions:

var body = self.get_component("RigidBody")
log.info("I weigh {body.mass} kg")
body.set_gravity(0.5)

self.get_component("Animator").play("run")
self.get_component("ParticleEmitter").emit(20)

Components are named without spaces: "RigidBody", "CharacterController", "Collider", "Renderer", "Animator", "Camera", "Script", "ParticleEmitter". get_component is an error when the object doesn’t have one; try_get_component gives back null instead. The actions of each component are listed under Component actions.

set_property sets any property of any component, by the component’s type name and the property’s name:

self.set_property("PointLightComponent", "intensity", 4.0)
self.set_property("AudioSourceComponent", "play_requested", true)

The component reference has every component’s type name and properties.

Finding objects

var player = Scene.find("Player")             // the first one, or null
var keys = Scene.find_all("Key")              // every one with that name
var enemies = Scene.with_tag("enemy")         // every one with the tag
var near = Scene.objects_within(self.position, 5.0)

var hit = Scene.raycast(self.position, Vec3.down, 10.0)
if hit != null {
    log.info("{hit.distance} units above {hit.object.name}")
}

Making and removing objects

var crate = Scene.spawn("assets://prefabs/crate.ofab", self.position)
Scene.destroy()     // removes this object, at the end of the frame

Messages and timers

send("handler", args...) calls a function on the object’s scripts: see Hooks and events. after, every and cancel run a function later or repeatedly, and are in the same page’s timers.