Core

Transform

Basic Concepts

Transform is a basic component that comes with an Entity. Developers can use it to manage the position, rotation, and scale of an Entity in local space and world space.

For a deeper understanding, refer to Galacean's Coordinate System.

Editor Usage

merge

Change the visualization transform component of the selected entity by directly using the mouse to manipulate the helper gizmo axes.

Move

IconActionShortcut
Switch to Move ModeW

Click the helper axis to drag the selected entity in a single direction. Click the helper plane to drag the selected entity in a single plane.

Rotate

IconActionShortcut
Switch to Rotate ModeE

Click and drag to change the rotation of the selected entity. Red represents rotation around the X-axis, green represents rotation around the Y-axis, and blue represents rotation around the Z-axis.

Scale

IconActionShortcut
Switch to Scale ModeR

Click the center cube to uniformly scale the selected entity on all axes. Click the helper axis to scale the selected entity in a single direction.

Through the Inspector Panel, you can set more precise position, rotation, and scale information for nodes.

image.png

Script Usage

// Create a node
const scene = engine.sceneManager.activeScene;
const root = scene.createRootEntity("root");
const cubeEntity = root.createChild("cube");
 
// An entity comes with a transform component by default upon creation
// The transform component allows for geometric transformations on the entity
 
// Modify node translation, rotation, and scale
transform.position = new Vector3();
// Alternatively, use transform.setPosition(0, 0, 0);
 
transform.rotation = new Vector3(90, 0, 0);
// Alternatively, use transform.setRotation(90, 0, 0);
 
// You can also access the transform component via the entity's properties
cubeEntity.transform.scale = new Vector3(2, 1, 1);
// Alternatively, use cubeEntity.transform.setScale(2, 1, 1);
 
// Translate the cube entity locally
cubeEntity.transform.translate(new Vector3(10, 0, 0), true);
 
// Rotate the cube entity locally
cubeEntity.transform.rotate(new Vector3(45, 0, 0), true);

Component Properties

Property NameDescription
positionLocal translation
rotationLocal rotation - Euler angles
rotationQuaternionLocal rotation - Quaternion
scaleLocal scale
worldPositionWorld translation
worldRotationWorld rotation - Euler angles
worldRotationQuaternionWorld rotation - Quaternion
lossyWorldScaleWorld lossy scale - When the parent node scales and the child node rotates, the scale becomes skewed and cannot be accurately represented by Vector3, requiring a Matrix3x3 for correct representation
localMatrixLocal matrix
worldMatrixWorld matrix
worldForwardForward vector (unit vector in world space)
worldRightRight vector (unit vector in world space)
worldUpUp vector (unit vector in world space)

Component Methods

Method NameDescription
getWorldUpGet the up vector from the world matrix
getWorldRightGet the right vector from the world matrix
getWorldForwardGet the forward vector from the world matrix
lookAtRotate and ensure the world forward vector points to the target world position
registerWorldChangeFlagRegister a flag for world transformation changes
rotateRotate by a specified Euler angle
rotateByAxisRotate by a specified angle around a specified axis
translateTranslate by a specified direction and distance

Purpose of registerWorldChangeFlag

The transform component internally uses a dirty flag for a lot of computational optimization. Since the worldMatrix property of transform is also optimized with a dirty flag, if external components need to track whether the current transform's worldMatrix has changed, the state of its dirty flag needs to be obtained. The transform component provides the registerWorldChangeFlag method: this method returns an update flag, which will be triggered when the worldMatrix of the current transform is modified. For specific usage, refer to the camera component:

class Camera {
  onAwake() {
    this._transform = this.entity.transform;
    // Register the update flag
    this._isViewMatrixDirty = this._transform.registerWorldChangeFlag();
  }
  get viewMatrix() {
    // When the flag is updated, derive the viewMatrix from the worldMatrix
    if (this._isViewMatrixDirty.flag) {
      this._isViewMatrixDirty.flag = false;
      Matrix.invert(this._transform.worldMatrix, this._viewMatrix);
    }
    return this._viewMatrix;
  }
}

Was this page helpful?