Up to date

This page is up to date for Godot `4.2`. If you still find outdated information, please open an issue.

# 使用 3D 变换¶

## 欧拉角的问题¶

### 插值¶

• 旋转不会线性映射到方向, 因此它们插值并不总是会形成最短路径(即从 `270``0` 的度数与从 `270` 开始到 `360` 的度数不同, 即使角度是相同的).

• "万向节锁死" 正在发挥作用(第一个和最后一个旋转的轴对齐, 因此失去了一个自由度). 请参阅 维基百科关于Gimbal Lock 的页面 以了解这个问题的详细解释.

## 变换的介绍¶

Godot 里的方向使用 Transform3D 数据类型。每个 Node3D 节点都包含一个与父级变换相关的 `transform` 属性（如果父级是 Node3D 派生类型）。

```var basis = Basis()
# Contains the following default values:
basis.x = Vector3(1, 0, 0) # Vector pointing along the X axis
basis.y = Vector3(0, 1, 0) # Vector pointing along the Y axis
basis.z = Vector3(0, 0, 1) # Vector pointing along the Z axis
```

### 操作变换¶

```var axis = Vector3(1, 0, 0) # Or Vector3.RIGHT
var rotation_amount = 0.1
# Rotate the transform around the X axis by 0.1 radians.
transform.basis = Basis(axis, rotation_amount) * transform.basis
# shortened
transform.basis = transform.basis.rotated(axis, rotation_amount)
```

Node3D 中的一种方法简化了这个操作：

```# Rotate the transform around the X axis by 0.1 radians.
rotate(Vector3(1, 0, 0), 0.1)
# shortened
rotate_x(0.1)
```

```# Rotate around the object's local X axis by 0.1 radians.
rotate_object_local(Vector3(1, 0, 0), 0.1)
```

### 精度误差¶

```transform = transform.orthonormalized()
```

```transform = transform.orthonormalized()
transform = transform.scaled(scale)
```

### 获取信息¶

```bullet.transform = transform
bullet.speed = transform.basis.z * BULLET_SPEED
```

```# Get the direction vector from player to enemy
var direction = enemy.transform.origin - player.transform.origin
if direction.dot(enemy.transform.basis.z) > 0:
enemy.im_watching_you(player)
```

```# Remember that +X is right
if Input.is_action_pressed("strafe_left"):
translate_object_local(-transform.basis.x)
```

```# Keep in mind Y is up-axis
if Input.is_action_just_pressed("jump"):
velocity.y = JUMP_SPEED

move_and_slide()
```

### 设置信息¶

```# accumulators
var rot_x = 0
var rot_y = 0

func _input(event):
if event is InputEventMouseMotion and event.button_mask & 1:
# modify accumulated mouse rotation
rot_x += event.relative.x * LOOKAROUND_SPEED
rot_y += event.relative.y * LOOKAROUND_SPEED
transform.basis = Basis() # reset rotation
rotate_object_local(Vector3(0, 1, 0), rot_x) # first rotate in Y
rotate_object_local(Vector3(1, 0, 0), rot_y) # then rotate in X
```