Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
CharacterBody2D
繼承: PhysicsBody2D < CollisionObject2D < Node2D < CanvasItem < Node < Object
專門用於通過腳本移動的角色的 2D 物理物體。
說明
CharacterBody2D 是針對使用者控制的物理體的特化類。它們不會受到物理的影響,但會影響路徑上的其他物理體。除了由 PhysicsBody2D.move_and_collide() 提供的常見的碰撞偵測之外,它們主要用於提供移動對象的高階 API,能夠偵測牆壁和斜坡(move_and_slide() 方法)。因此適用於需要高度可配置的物理體,因為通常是使用者控制的角色,所以必須按照特定的方式移動、與世界發生碰撞。
如果是移動平臺等不需要複雜移動和碰撞偵測的遊戲物件,AnimatableBody2D 更方便配置。
教學
屬性
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
方法
void |
|
get_floor_angle(up_direction: Vector2 = Vector2(0, -1)) const |
|
get_floor_normal() const |
|
get_last_motion() const |
|
get_platform_velocity() const |
|
get_position_delta() const |
|
get_real_velocity() const |
|
get_slide_collision(slide_idx: int) |
|
get_slide_collision_count() const |
|
get_wall_normal() const |
|
is_on_ceiling() const |
|
is_on_ceiling_only() const |
|
is_on_floor() const |
|
is_on_floor_only() const |
|
is_on_wall() const |
|
is_on_wall_only() const |
|
列舉
enum MotionMode: 🔗
MotionMode MOTION_MODE_GROUNDED = 0
請在牆壁、天花板、地板等概念有意義時套用。在該模式下,物體運動會對斜坡作出反應(加減速)。該模式適合平臺跳躍等側視角遊戲。
MotionMode MOTION_MODE_FLOATING = 1
請在沒有地板和天花板等概念時套用。所有碰撞都會作為 on_wall(撞牆)彙報。在該模式下,滑動時的速度恒定。該模式適合俯視角遊戲。
enum PlatformOnLeave: 🔗
PlatformOnLeave PLATFORM_ON_LEAVE_ADD_VELOCITY = 0
離開移動平臺時,將最後的平臺速度新增到 velocity 中。
PlatformOnLeave PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY = 1
離開移動平臺時,將最後的平臺速度新增到 velocity 中,但是忽略向下的運動。如果想要在平臺向下移動時保持完整的跳躍高度,就非常有用。
PlatformOnLeave PLATFORM_ON_LEAVE_DO_NOTHING = 2
離開平臺時什麼也不做。
屬性說明
bool floor_block_on_wall = true 🔗
如果為 true,則該物體將只能在地板上移動。此選項能夠避免在牆壁上行走,但允許沿牆壁向下滑動。
bool floor_constant_speed = false 🔗
如果為 false(預設),則該物體在下坡時會移動得更快,在上坡時會移動得更慢。
如果為 true,則無論坡度如何,該物體在地面上都會以相同的速度移動。請注意,你需要使用 floor_snap_length 以恒定速度黏著至向下的斜坡。
float floor_max_angle = 0.7853982 🔗
呼叫 move_and_slide() 時,斜坡仍被視為地板(或天花板)而不是牆壁的最大角度(單位為弧度)。預設值等於 45 度。
float floor_snap_length = 1.0 🔗
設定吸附距離。設為非 0.0 值時,該物體在呼叫 move_and_slide() 時會保持附著到斜坡上。吸附向量會根據給定的距離和 up_direction 反方向決定。
只要吸附向量與地面有接觸,該物體就會逆 up_direction 移動,保持附著到表面。如果該物體是沿著 up_direction 移動的,則不會套用吸附,這樣跳躍時或者被其他物體推動時就能夠不再附著地面。如果想要在套用吸附時無視速度,請使用 apply_floor_snap()。
bool floor_stop_on_slope = true 🔗
如果為 true,則該物體靜止時,呼叫 move_and_slide() 不會讓它在斜坡上發生滑動。
如果為 false,則 velocity 施加向下的力時,該物體會在地板的斜坡上發生滑動。
呼叫 move_and_slide() 時,物體在停止之前可以改變方向的最大次數。必須大於零。
MotionMode motion_mode = 0 🔗
void set_motion_mode(value: MotionMode)
MotionMode get_motion_mode()
設定運動模式,定義 move_and_slide() 的行為。
int platform_floor_layers = 4294967295 🔗
用於偵測地板物體的碰撞層,該地板物體會被用作 CharacterBody2D 所要跟隨的移動平臺。預設情況下會偵測所有地板物體並傳播其速度。
PlatformOnLeave platform_on_leave = 0 🔗
void set_platform_on_leave(value: PlatformOnLeave)
PlatformOnLeave get_platform_on_leave()
設定離開移動平台時要應用的行為。為了達到物理準確,預設會應用你離開時最後的平台速度。
int platform_wall_layers = 0 🔗
用於偵測牆壁物體的碰撞層,該牆壁物體會被用作 CharacterBody2D 所要跟隨的移動平臺。預設情況下會忽略所有牆壁物體。
額外邊距,用於在呼叫 move_and_slide() 時進行碰撞恢復。
如果該物體與另一個物體至少有這麼近,就會認為它們正在碰撞,並在執行實際運動前推開。
值較高時,對碰撞的偵測會更加靈活,有助於持續偵測牆壁和地板。
值較低時,會強制碰撞演算法進行更精確的偵測,因此可以在特別需要精度的情況下使用,例如在非常低的縮放下避免可見的抖動,或者為了讓一堆角色物體的達到穩定。
bool slide_on_ceiling = true 🔗
如果為 true,則該物體在跳到天花板時會滑動;如果為 false,則會停止並垂直下落。
Vector2 up_direction = Vector2(0, -1) 🔗
指向上方的向量,用於在呼叫 move_and_slide() 時判定何者爲牆壁、何者爲地板(或天花板)。預設爲 Vector2.UP。由於向量會被正規化,因此不能等於 Vector2.ZERO;若希望所有碰撞皆被判定爲撞牆,請考慮使用 MOTION_MODE_FLOATING 作為 motion_mode。
Vector2 velocity = Vector2(0, 0) 🔗
以每秒像素爲單位的速度向量,在呼叫 move_and_slide() 時會被使用及修改。
注意:有個常見的錯誤是將此屬性設爲目標速度乘以 delta,這會變成以像素為單位的運動向量。
float wall_min_slide_angle = 0.2617994 🔗
物體遇到牆面時允許發生滑動的最小角度(單位為弧度)。預設值等於 15 度。只有在 motion_mode 為 MOTION_MODE_FLOATING 時該屬性才會影響運動。
方法說明
void apply_floor_snap() 🔗
允許手動套用向地板的吸附,無論該物體的速度多大。is_on_floor() 返回 true 時這個函式什麼都不做。
float get_floor_angle(up_direction: Vector2 = Vector2(0, -1)) const 🔗
回傳地板在最近一次碰撞點的碰撞角度,依據為 up_direction,預設為 Vector2.UP。該值始終為正數,只有在呼叫了 move_and_slide() 並且 is_on_floor() 回傳值為 true 時才有效。
Vector2 get_floor_normal() const 🔗
回傳最近一次碰撞點的地面法線。只有在呼叫了 move_and_slide() 並且 is_on_floor() 回傳值為 true 時才有效。
警告:碰撞法線並不總是與表面法線相同。
Vector2 get_last_motion() const 🔗
返回最近一次呼叫 move_and_slide() 時施加給該 CharacterBody2D 的最後一次運動。如果發生了滑動,則該移動可以拆分為多次運動,此方法返回的是最後一次,可用於取得目前的移動方向。
KinematicCollision2D get_last_slide_collision() 🔗
如發生碰撞則回傳一個 KinematicCollision2D。回傳值包含了最近一次呼叫 move_and_slide() 期間發生的最後一次碰撞的資訊。若無碰撞發生,則回傳 null。另見 get_slide_collision()。
Vector2 get_platform_velocity() const 🔗
返回位於最近一次碰撞點的平臺線速度。僅在呼叫 move_and_slide() 後有效。
Vector2 get_position_delta() const 🔗
返回最近一次呼叫 move_and_slide() 所產生的運動(位置差異量)。
Vector2 get_real_velocity() const 🔗
返回最近一次呼叫 move_and_slide() 之後的目前真實速度。例如,即便速度為水平方向,爬坡時你也會斜向移動。此方法返回的就是那個斜向移動,與返回請求速度的 velocity 相對。
KinematicCollision2D get_slide_collision(slide_idx: int) 🔗
回傳 KinematicCollision2D,包含最近一次呼叫 move_and_slide() 時發生的碰撞資訊。因為單次呼叫 move_and_slide() 可能發生多次碰撞,所以你必須指定碰撞索引,範圍為 0 到 (get_slide_collision_count() - 1)。另見 get_last_slide_collision()。
範例:使用 for 循環遍歷碰撞:
for i in get_slide_collision_count():
var collision = get_slide_collision(i)
print("碰到了:", collision.get_collider().name)
for (int i = 0; i < GetSlideCollisionCount(); i++)
{
KinematicCollision2D collision = GetSlideCollision(i);
GD.Print("碰到了:", (collision.GetCollider() as Node).Name);
}
int get_slide_collision_count() const 🔗
返回最近一次呼叫 move_and_slide() 時,該物體發生碰撞並改變方向的次數。
Vector2 get_wall_normal() const 🔗
回傳最近一次碰撞點的牆面法線。只有在呼叫了 move_and_slide() 並且 is_on_wall() 回傳值為 true 時才有效。
警告:碰撞法線並不總是與表面法線相同。
如果最近一次呼叫 move_and_slide() 時,該物體和天花板發生了碰撞,則返回 true。否則返回 false。決定表面是否為“天花板”的是 up_direction 和 floor_max_angle。
bool is_on_ceiling_only() const 🔗
如果最近一次呼叫 move_and_slide() 時,該物體僅和天花板發生了碰撞,則返回 true。否則返回 false。決定表面是否為“天花板”的是 up_direction 和 floor_max_angle。
如果最近一次呼叫 move_and_slide() 時,該物體和地板發生了碰撞,則返回 true。否則返回 false。決定表面是否為“地板”的是 up_direction 和 floor_max_angle。
bool is_on_floor_only() const 🔗
如果最近一次呼叫 move_and_slide() 時,該物體僅和地板發生了碰撞,則返回 true。否則返回 false。決定表面是否為“地板”的是 up_direction 和 floor_max_angle。
如果最近一次呼叫 move_and_slide() 時,該物體和牆壁發生了碰撞,則返回 true。否則返回 false。決定表面是否為“牆壁”的是 up_direction 和 floor_max_angle。
bool is_on_wall_only() const 🔗
如果最近一次呼叫 move_and_slide() 時,該物體僅和牆壁發生了碰撞,則返回 true。否則返回 false。決定表面是否為“牆壁”的是 up_direction 和 floor_max_angle。
根據 velocity 移動該物體。該物體如果與其他物體發生碰撞,則會沿著對方滑動(預設只在地板上滑動),不會立即停止移動。如果對方是 CharacterBody2D 或 RigidBody2D,還會受到對方運動的影響。可以用於製作移動、旋轉的平台,也可用於推動其他節點。
該方法在計算時會自動使用物理步驟的 delta,所以應當在 Node._physics_process()(或 Node._physics_process() 中呼叫的方法)中使用。否則執行仿真會使用錯誤的速度。
發生滑動碰撞時會改變 velocity。要取得最後一次碰撞,請呼叫 get_last_slide_collision(),要取得碰撞的更多資訊,請使用 get_slide_collision()。
該物體接觸到移動平台時,平台的速度會自動加入到該物體的運動中。平台運動所造成的碰撞始終為所有滑動碰撞中的第一個。
通用行為和可用屬性會根據 motion_mode 發生改變。
如果該物體發生了碰撞,則回傳 true,否則回傳 false。