Moving things
CompilesWhat you’re moving decides how. An ordinary object moves when you change its transform. Players and balls have scripts that own their position, so work with those scripts.
| Moving | How | Where |
|---|---|---|
| An ordinary object | Write its transform |
Any event |
| A player | Write their transform, then tell player_movement the new facing |
late_tick, on every machine |
| A loose ball | Ask its ball_transform with an event |
Any event |
An ordinary object
Section titled “An ordinary object”position and rotation in a transform are relative to the entity’s parent:
let transform: Component = $support.entity_get_component($entity.get(), "transform.vscript")transform.position = transform.position + vec3(0, 0, 50)Something that moves every frame
Section titled “Something that moves every frame”Work the position out from the clock instead of adding a little each frame, so it can’t drift:
let height: float = 60.0let seconds_per_cycle: float = 3.0let mut transform: Component = nulllet mut start: vec3 = vec3(0, 0, 0)
event export fn created() { transform = $support.entity_get_component($entity.get(), "transform.vscript") start = transform.position}
event export fn tick() { let seconds: float = $time.ms_to_seconds($time.get_gameplay_time_ms()) let wave: float = $math.sin(seconds / seconds_per_cycle * 6.2831855) transform.position = start + $math.vec3(0.0, 0.0, wave * height)}Motion computed from the clock looks the same on every machine without sending anything, so a script like this
can switch replication off: $net.set_replicated(false, false) in type_created.
Turn to face a direction
Section titled “Turn to face a direction”Rotations are quaternions. Build one from an axis and an angle. z is up, so turning around z is turning left
and right:
fn face_yaw(transform: Component, degrees: float) { transform.rotation = $math.rotation_from_axis_angle(vec3(0, 0, 1), $math.deg2rad(degrees))}A player
Section titled “A player”Three things have to be right:
- Where: in
late_tick. A player’s movement writes their position late in the frame; anything written earlier is overwritten. - Who: every machine. Each player’s game simulates their movement too, so a move made only on the server is undone by the client.
- Facing: tell
player_movementthe new yaw, or the camera snaps back to the old direction.
let mut pending_player: Component = nulllet mut pending_position: vec3 = vec3(0, 0, 0)
event export fn type_created() { $net.set_replicated(true, false) // and no is_server() guard below}
// Call this from wherever you decide to move them: a trigger, a timer.fn request_move(player: Component, where: vec3) { pending_player = player pending_position = where}
event export fn late_tick() { if !pending_player { return } let body: Entity = $component.get_entity(pending_player) pending_player = null let transform: Component = $support.entity_get_component(body, "transform.vscript") if transform { transform.position = pending_position }}To also turn them, set transform.rotation and send the yaw on:
fn turn_player(body: Entity, rotation: vec4) { let transform: Component = $support.entity_get_component(body, "transform.vscript") transform.rotation = rotation let movement: Component = $support.entity_get_component(body, "player_movement.vscript") if movement { $component.queue_event("force_set_player_yaw", movement, [$math.eulers_from_rotation(rotation).z], false) }}A ball
Section titled “A ball”A ball’s ball_transform owns where it is. Ask it to move with the event it provides:
fn move_ball(ball: Component, where: vec3, rotation: vec4) { $component.queue_event("set_position_and_rotation", ball, [where, rotation], true)}Leave balls someone is holding alone. See Triggers for how to tell.