Builtin Library
README.md
entityOps.transform
Move, rotate and scale entities that already exist — over one or many entities.
entityOps.transform("lamp", { position = { 0, 3, 0 } })
entityOps.transform({ "wall_n", "wall_s" }, { offset = { 0, 2, 0 } })
entityOps.transform({ name = { "wall" } }, { offset = { 0, 2, 0 } })
entityOps.transform("crate", { rotation = { 0, 45, 0 }, scale = 2 })
entityOps.transform("lamp") -- no ops: a pure read
Targets take a name or id, a list of them, scene.find records, or a
query resolved for you — so you can move everything matching
{ name = { "wall" } } without looking the entities up first.
Absolute ops carry their space in the name: position / rotation
are world, localPosition / localRotation are parent-relative, scale
is a number or {x,y,z}.
Relative ops are offset (position delta), rotate (applied on top
of the current rotation) and scaleBy (multiplier). space —
"world" (default) or "local" — governs these.
snap quantizes the resulting position to grid steps.
Rotations take a {x,y,z,w} quaternion or {pitch,yaw,roll} euler
degrees, the same forms entityOps.spawn accepts.
Absolute and relative forms of one channel are exclusive — passing
position and offset together is an error rather than a silent
precedence rule.
An option key outside the documented set is an error that names it and
lists the accepted keys, so a mistyped positon is reported instead of
returning a successful-looking read of an entity that never moved.
Per-entity values in one call:
entityOps.transform({
{ target = "wall_n", position = { 0, 1, -5 }, rotation = { 0, 0, 0 } },
{ target = "wall_e", position = { 5, 1, 0 }, rotation = { 0, 90, 0 } },
})
Every record is validated and resolved before any of them is applied, so a bad entry fails the whole call rather than moving its siblings and leaving itself behind.
Every call returns the resulting
{ id, name, position, localPosition, rotation, localRotation, eulerAngles, scale, parent }
per entity — the mutation and the read are the same call.