界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
开发与工程 · SKILL.md

physics

physics

【开发与工程】Implement 2D and 3D physics in Godot including collision detection, physics bodies, raycasting, and area detection. Use this skill when setting up CharacterBody, RigidBody, StaticBody, configuring collision layers and masks, casting rays, or building physics-driven gameplay.

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: physics description: Implement 2D and 3D physics in Godot including collision detection, physics bodies, raycasting, and area detection. Use this skill when setting up CharacterBody, RigidBody, StaticBody, configuring collision layers and masks, casting rays, or building physics-driven gameplay. metadata: author: godot-dev version: "1.0"

Physics System

Physics Body Types

CharacterBody2D/3D

For player-controlled characters with manual physics handling.

extends CharacterBody2D

@export var speed: float = 300.0
@export var jump_velocity: float = -500.0

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):
    if not is_on_floor():
        velocity.y += gravity * delta

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_velocity

    var direction = Input.get_axis("left", "right")
    velocity.x = direction * speed

    move_and_slide()

    for i in get_slide_collision_count():
        var collision = get_slide_collision(i)
        if collision.get_collider().is_in_group("enemies"):
            take_damage()

RigidBody2D/3D

For physics-driven objects (balls, ragdolls, projectiles).

extends RigidBody2D

@export var launch_force: float = 500.0

func launch(direction: Vector2):
    apply_central_impulse(direction * launch_force)

func _ready():
    apply_central_impulse(Vector2(100, -200))
    gravity_scale = 1.5
    physics_material_override = PhysicsMaterial.new()
    physics_material_override.bounce = 0.8

StaticBody2D/3D

For static environment colliders (walls, floors, platforms).

# Moving platform with AnimatableBody2D
extends AnimatableBody2D

@export var move_distance: Vector2 = Vector2(0, -100)
@export var move_speed: float = 2.0

var start_position: Vector2
var target_position: Vector2

func _ready():
    start_position = global_position
    target_position = start_position + move_distance

func _physics_process(delta):
    global_position = global_position.lerp(target_position, move_speed * delta)
    if global_position.distance_to(target_position) < 1:
        var temp = target_position
        target_position = start_position
        start_position = temp

Area2D/3D

For trigger zones (pickups, damage zones, detection areas).

extends Area2D

signal collected()

func _ready():
    body_entered.connect(_on_body_entered)
    area_entered.connect(_on_area_entered)

func _on_body_entered(body: Node2D):
    if body.is_in_group("player"):
        collected.emit()
        queue_free()

func _on_area_entered(area: Area2D):
    if area.is_in_group("damage_zone"):
        take_damage()

Collision Setup

Collision Layers & Masks

  • Layer: Which layer this object is ON
  • Mask: Which layers this object can INTERACT WITH

Example setup:

  • Layer 1: Player
  • Layer 2: Enemies
  • Layer 3: Environment
  • Layer 4: Pickups
collision_layer = 1  # Player layer
collision_mask = 5   # Interact with layers 1 and 3 (1 + 4 = 5)

CollisionShape2D/3D

Required for physics bodies. Common shapes:

  • RectangleShape2D: Boxes, walls
  • CircleShape2D: Spheres, balls
  • CapsuleShape2D: Characters
  • PolygonShape2D: Custom shapes

Raycasting

2D Raycast

extends Node2D

@onready var ray_cast = $RayCast2D

func _physics_process(delta):
    ray_cast.target_position = Vector2(100, 0)
    if ray_cast.is_colliding():
        var collider = ray_cast.get_collider()
        var point = ray_cast.get_collision_point()
        var normal = ray_cast.get_collision_normal()
        if collider.is_in_group("enemy"):
            attack(collider)

3D Raycast

extends Node3D

@onready var ray_cast = $RayCast3D

func _physics_process(delta):
    ray_cast.target_position = Vector3(0, 0, -10)
    if ray_cast.is_colliding():
        var collider = ray_cast.get_collider()
        if collider.has_method("take_damage"):
            collider.take_damage(10)

PhysicsDirectSpaceState (Advanced)

func raycast_from_mouse():
    var space_state = get_world_2d().direct_space_state
    var mouse_pos = get_global_mouse_position()
    var query = PhysicsRayQueryParameters2D.create(global_position, mouse_pos)
    query.collision_mask = 2
    var result = space_state.intersect_ray(query)
    if result:
        print("Hit: ", result.collider.name)

Best Practices

  1. Use appropriate body types: CharacterBody for manual control, RigidBody for physics objects, StaticBody for walls, Area for triggers
  2. Collision layers: Keep layers organized; use minimal masks for performance
  3. Physics process: Use _physics_process() for all physics calculations — fixed timestep ensures consistent behavior
  4. Performance: Use simple collision shapes; disable physics for off-screen objects; use freeze on RigidBody when not needed
我的收藏