You do not need to abandon Euler angles completely. In Lenga, the normal workflow is:
- use Euler angles in the Inspector when that is the easiest way to author a starting orientation
- use
Quaternionin code when you want safer 3D rotation math
What a Quaternion Is in Practice
In day-to-day Lenga use, a quaternion is simply a rotation value that is better suited to combining and applying 3D rotations than adding Euler angles together.
You will usually touch it through:
Transform::$localRotationTransform::$rotationQuaternion::fromEulerAngles(...)
When To Use Euler Angles
Euler angles are still useful when you want:
- a readable starting rotation in the Inspector
- a simple one-off rotation in degrees
- to quickly see
X,Y, andZvalues while authoring
When To Use Quaternions
Use quaternions when you want:
- to combine multiple 3D rotations safely
- to rotate an object relative to its current orientation
- to work with parented 3D objects
- camera and aiming workflows that should not depend on Euler-angle addition
Step-by-Step Workflow
1. Start with a normal 3D object
Create or select a 3D object that already has a Transform.
You can still set its starting rotation in the Inspector using normal Euler fields.
2. Convert a familiar Euler rotation into a quaternion
use Lenga\Engine\Core\Quaternion;
use Lenga\Engine\Core\Vector3;
$yaw = Quaternion::fromEulerAngles(new Vector3(0.0, 90.0, 0.0));
This is the easiest way to begin if you are thinking in degrees.
3. Apply the quaternion to the transform
For a world rotation:
$this->transform->rotation = $yaw;
For a local rotation relative to the parent:
$this->transform->localRotation = $yaw;
4. Combine rotations
If you want to combine rotations, multiply them together.
$yaw = Quaternion::fromEulerAngles(new Vector3(0.0, 90.0, 0.0));
$pitch = Quaternion::fromEulerAngles(new Vector3(-15.0, 0.0, 0.0));
$this->transform->localRotation = $yaw->multiply($pitch);
This is the common pattern for things like turret aiming, camera pitch/yaw, and parented 3D props.
5. Use the transform directions
Once the transform has a rotation, its direction vectors follow that rotation.
$forward = $this->transform->forward;
$right = $this->transform->right;
$up = $this->transform->up;
These are useful for movement, aiming, and spawning projectiles in front of an object.
Example: Simple Camera Orbit Step
use Lenga\Engine\Core\Behaviour;
use Lenga\Engine\Core\Quaternion;
use Lenga\Engine\Core\Time;
use Lenga\Engine\Core\Vector3;
class OrbitCamera extends Behaviour
{
public function update(): void
{
$yawDelta = Quaternion::fromEulerAngles(
new Vector3(0.0, 45.0 * Time::deltaTime(), 0.0)
);
$this->transform->rotation = $yawDelta->multiply($this->transform->rotation);
}
}
Inspector and Scene Interop
Lenga's Inspector remains mainly Euler-facing in this release.
That means:
- you still edit the visible rotation fields as Euler angles
Transformcomposes 3D rotations internally using quaternion-backed math- scene data remains Inspector-friendly, while runtime rotation workflows can still use quaternions in code
Common Gotchas
rotationis world rotation.localRotationis rotation relative to the parent.eulerAnglesandlocalEulerAnglesare still valid, but they are not the best way to combine complex 3D rotations in code.- Parented objects are exactly where quaternion-backed rotation becomes most useful. If a parent rotates, the child rotation workflow stays safer than plain Euler-angle addition.
forwardin Lenga's 3D transform points along the object's rotated forward direction, so use that instead of guessing which axis to move along.