Up to date

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

# 运动学角色（2D）¶

## 前言¶

• 动力学角色控制器使用的是一个具有无限惯性张量的刚体。这是一个不能旋转的刚体. 物理引擎总是让物体移动和碰撞, 然后一并解决它们的碰撞. 这使得动态角色控制器能够与其他物理对象无缝交互, 就像在平台游戏演示中看到的那样. 然而, 这些互动并不总是可预测的. 碰撞可能需要多于一帧的时间来解决, 所以几个碰撞可能看起来会有很小的位移. 这些问题是可以解决的, 但需要一定的技巧.

• 运动学角色控制器总是假设以非碰撞状态开始，并将总是移动到非碰撞状态。如果它开始时处于碰撞状态, 将像刚体一样尝试释放自己, 但这是特例, 而不是规则. 这使得它们的控制和运动更可预测, 更容易编程. 然而, 有一个缺点, 它们不能直接与其他物理对象交互, 除非在代码中手动完成.

This short tutorial focuses on the kinematic character controller. It uses the old-school way of handling collisions, which is not necessarily simpler under the hood, but well hidden and presented as an API.

## 物理过程处理¶

```extends CharacterBody2D

func _physics_process(delta):
pass
```

## 场景设置¶

To have something to test, here's the scene (from the tilemap tutorial): kinematic_character_2d_starter.zip. We'll be creating a new scene for the character. Use the robot sprite and create a scene like this:

## 移动动态角色¶

Go back to the character scene, and open the script, the magic begins now! Kinematic body will do nothing by default, but it has a useful function called `CharacterBody2D.move_and_collide()`. This function takes a Vector2 as an argument, and tries to apply that motion to the kinematic body. If a collision happens, it stops right at the moment of the collision.

```extends CharacterBody2D

func _physics_process(delta):
move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame
```

```extends CharacterBody2D

const GRAVITY = 200.0

func _physics_process(delta):
velocity.y += delta * GRAVITY

var motion = velocity * delta
move_and_collide(motion)
```

This adds basic support for walking when pressing left and right:

```extends CharacterBody2D

const GRAVITY = 200.0
const WALK_SPEED = 200

func _physics_process(delta):
velocity.y += delta * GRAVITY

if Input.is_action_pressed("ui_left"):
velocity.x = -WALK_SPEED
elif Input.is_action_pressed("ui_right"):
velocity.x =  WALK_SPEED
else:
velocity.x = 0

# "move_and_slide" already takes delta time into account.
move_and_slide()
```