Token导航 LogoToken导航TokenDH.com
开发权限需确认github未标认证来源可访问许可证需确认审计通过

godot-2d-physics戈多二维物理

Agent Skill

godot-2d-physics 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

3,058

周安装

130

GitHub Stars

138

下载量

1,071
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:godot-2d-physics(戈多二维物理)
来源仓库:https://github.com/thedivergentai/gd-agentic-skills
仓库路径:skills/godot-2d-physics
安装命令:
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-2d-physics
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-2d-physics

简介

godot-2d-physics 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。

  • 适用于 GitHub 仓库管理和代码协作相关任务。
  • 围绕仓库状态、代码变更或协作事项进行整理。
  • 安装命令:npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-2d-physics。
  • 建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

SKILL.md

2D Physics

Expert guidance for collision detection, triggers, and raycasting in Godot 2D.

NEVER Do

  • NEVER scale CollisionShape2D nodes — Use the shape handles in the editor, NOT the Node2D scale property. Scaling causes unpredictable physics behavior and incorrect collision normals [12].
  • NEVER confuse collision_layer with collision_mask — Layer = "What AM I?", Mask = "What do I DETECT?". Setting both to the same value is usually wrong [13].
  • NEVER multiply velocity by delta when using move_and_slide()move_and_slide() automatically includes timestep. Only multiply gravity/acceleration by delta [14].
  • NEVER forget force_raycast_update() for manual mid-frame raycasts — Raycasts update once per physics frame. If you change target_position, you MUST force an update [15].
  • NEVER use get_overlapping_bodies() every frame — It is expensive. Cache results with body_entered/body_exited signals instead [16].
  • NEVER modify RigidBody2D state directly in _process — Use _integrate_forces() for safe, synchronized access to PhysicsDirectBodyState2D [17, 411].
  • NEVER move PhysicsBody2D nodes in _process() — Use _physics_process(). Moving bodies outside the physics step causes stutter and unreliable collision detection.
  • NEVER use RigidBody2D for 1000+ simple entities — Use PhysicsServer2D to bypass node overhead for massive performance gains (Swarms/Bullets) [18, 397].
  • NEVER use Area2D for high-frequency blocking (Bullets) — Area signals can be delayed. Use move_and_collide() or ShapeCast2D for frame-perfect results [19].
  • NEVER ignore 'Physics Jitter' on high-refresh monitors — Enable Physics Interpolation to prevent micro-stutter in motion [21, 400].
  • NEVER scale collision shapes directly at runtime — It causes major instability. Resize the shape resource (size/radius) instead.
  • NEVER use set_deferred for immediate physics transform logic — It happens at the end of the frame. Use force_raycast_update() or PhysicsServer2D instead.
  • NEVER leave Continuous CD (CCD) enabled for slow objects — It adds significant CPU overhead. Reserve it for high-speed projectiles to prevent tunneling.
  • NEVER use a single collision layer for all tiles/entities — Separate layers (Ground, Walls, Enemies) to allow selective filtering via masks.
  • NEVER forget to free PhysicsServer2D RIDs manually — They are not garbage collected and will leak memory permanently.

Available Scripts

MANDATORY: Read the script matching your use case before implementation.

collision_setup.gd

Programmatic layer/mask management with named layer constants and debug visualization.

physics_query_cache.gd

Frame-based caching for PhysicsDirectSpaceState2D queries - eliminates redundant expensive queries.

custom_physics.gd

Custom physics integration patterns for CharacterBody2D. Covers non-standard gravity, forces, and manual stepping. Use for non-standard physics behavior.

physics_queries.gd

PhysicsDirectSpaceState2D query patterns for raycasting, point queries, and shape queries. Use for line-of-sight, ground detection, or area scanning.

physics_server_swarm.gd

Low-level PhysicsServer2D usage for thousands of moving objects. Bypasses node overhead for massive performance gains in bullet hells or swarms.

substepping_logic.gd

Manual physics sub-stepping for high-velocity projectiles. Ensures frame-perfect collision for objects moving faster than the physics tick.

safe_rigidbody_state.gd

Thread-safe RigidBody2D modification using _integrate_forces. Ideal for teleporting bodies or applying custom impulses without jitter.

physics_direct_query.gd

Lighweight environment sensing using PhysicsDirectSpaceState2D. Performs ray queries without the overhead of RayCast2D nodes.

collision_bitmask_helper.gd

Clean architectural pattern for managing complex collision layers/masks using bitwise Enums and helpers.

raycast_vision_stack.gd

Optimized multicasting vision system for AI. Reuses a single RayCast2D to check multiple angles in one physics frame.

shapecast_aoe.gd

Robust AOE detection using ShapeCast2D. Provides instant collision information without the signal-lag of Area2D.

custom_gravity_override.gd

Logic for localized gravity zones (Water, Space, Wind) and manual character-weight simulation.

collision_debouncer.gd

Expert pattern for preventing signal spam when multi-shape bodies enter triggers.

jitter_interpolation_fix.gd

Standard configuration and runtime adjustments to ensure smooth character movement on high-refresh-rate monitors.

physics_server_direct_body.gd

Direct PhysicsServer2D RID management for peak performance in massive physics simulations.

move_and_collide_precision.gd

Expert bounce and friction logic implementation for precision-critical movement.

continuous_collision_detection.gd

Advanced CCD management for preventing bullet tunneling at extremely high velocities.

performance_batch_mover.gd

Optimized batch movement for multiple static/animatable bodies using riders-aware logic.


Collision Layers & Masks (Bitmask Deep Dive)

The Mental Model

# collision_layer (32 bits): What broadcast channels am I transmitting on?
# collision_mask (32 bits): What broadcast channels am I listening to?

# Example: Player vs Enemy
# Player:
#   layer = 0b0001 (Channel 1: "I am a player")
#   mask  = 0b0110 (Channels 2+3: "I listen for enemies and walls")
# Enemy:
#   layer = 0b0010 (Channel 2: "I am an enemy")
#   mask  = 0b0101 (Channels 1+3: "I listen for players and walls")

Bitmask Helpers

# ✅ GOOD: Use helper functions for clarity
func setup_player_collision() -> void:
    # I am layer 1
    set_collision_layer_value(1, true)

    # I detect layers 2 (enemies) and 3 (world)
    set_collision_mask_value(2, true)
    set_collision_mask_value(3, true)

# ✅ GOOD: Bit shift for programmatic layer math
func enable_layers(base_layer: int, count: int) -> void:
    var mask := 0
    for i in range(count):
        mask |= (1 << (base_layer + i - 1))
    collision_mask = mask

# ❌ BAD: Hardcoded bitmasks without documentation
collision_mask = 0b110110  # What does this mean?!

Common Patterns

# Pattern: Projectile that hits enemies but ignores other projectiles
# projectile.gd
extends Area2D

func _ready() -> void:
    set_collision_layer_value(4, true)   # Layer 4: "Projectiles"
    set_collision_mask_value(2, true)    # Mask Layer 2: "Enemies"
    # Result: Projectiles don't collide with each other

# Pattern: One-way platform (player can jump through from below)
# platform.gd
extends StaticBody2D

@export var one_way := true

func _ready() -> void:
    set_collision_layer_value(3, true)   # Layer 3: "World"
    if one_way:
        # Use Area2D + collision exemption instead
        # (Standard one-way platforms use different technique)
        pass

Area2D Expert Patterns

Problem: Duplicate Triggers on Multi-CollisionShape

# ❌ BAD: body_entered fires MULTIPLE times if Area2D has multiple shapes
extends Area2D

func _ready() -> void:
    body_entered.connect(_on_body_entered)

func _on_body_entered(body: Node2D) -> void:
    print("Entered!")  # Fires 3x if Area has 3 CollisionShapes!

# ✅ GOOD: Track unique bodies with Set
extends Area2D

var _active_bodies := {}  # Use dict as Set

func _ready() -> void:
    body_entered.connect(_on_body_entered)
    body_exited.connect(_on_body_exited)

func _on_body_entered(body: Node2D) -> void:
    if body not in _active_bodies:
        _active_bodies[body] = true
        print("First entrance!")  # Fires once

func _on_body_exited(body: Node2D) -> void:
    _active_bodies.erase(body)

Damage-Over-Time with Immunity Frames

# lava_zone.gd
extends Area2D

@export var damage_per_tick := 5
@export var tick_rate := 0.5  # Damage every 0.5s

var _damage_timers := {}  # body -> time_until_next_tick

func _ready() -> void:
    body_entered.connect(_on_body_entered)
    body_exited.connect(_on_body_exited)

func _on_body_entered(body: Node2D) -> void:
    if body.has_method("take_damage"):
        _damage_timers[body] = 0.0  # Immediate first tick

func _on_body_exited(body: Node2D) -> void:
    _damage_timers.erase(body)

func _process(delta: float) -> void:
    for body in _damage_timers.keys():
        _damage_timers[body] -= delta
        if _damage_timers[body] <= 0.0:
            body.take_damage(damage_per_tick)
            _damage_timers[body] = tick_rate

RayCast2D Advanced Usage

Dynamic Raycast Rotation

# enemy_vision.gd - Enemy looks toward player
extends CharacterBody2D

@onready var vision_ray: RayCast2D = $VisionRay

func can_see_target(target: Node2D) -> bool:
    var direction := global_position.direction_to(target.global_position)
    vision_ray.target_position = direction * 300  # 300px range
    vision_ray.force_raycast_update()  # CRITICAL: Update mid-frame

    if vision_ray.is_colliding():
        return vision_ray.get_collider() == target
    return false

Multipa Raycasts for Ledge Detection

# platformer_controller.gd
extends CharacterBody2D

@onready var floor_front: RayCast2D = $FloorCheckFront
@onready var floor_back: RayCast2D = $FloorCheckBack

func at_ledge() -> bool:
    return floor_front.is_colliding() and not floor_back.is_colliding()

func _physics_process(delta: float) -> void:
    if at_ledge() and is_on_floor():
        # Enemy AI: Turn around at ledges
        velocity.x *= -1

Raycast Exclusions

# Ignore specific bodies (e.g., self)
func _ready() -> void:
    $RayCast2D.add_exception(self)
    $RayCast2D.add_exception($Weapon)  # Ignore attached weapon collider

# Reset exclusions
$RayCast2D.clear_exceptions()

PhysicsDirectSpaceState2D (Manual Queries)

Point Query: Click Detection

# Check if mouse click hits any physics body
func get_body_at_mouse() -> Node2D:
    var mouse_pos := get_global_mouse_position()
    var space := get_world_2d().direct_space_state

    var query := PhysicsPointQueryParameters2D.new()
    query.position = mouse_pos
    query.collide_with_areas = false
    query.collision_mask = 0b11111111  # All layers

    var results := space.intersect_point(query, 1)  # Max 1 result
    if results.is_empty():
        return null
    return results[0].collider

Shape Cast: AOE Attack

# AOE damage in circle around player
func damage_nearby_enemies(center: Vector2, radius: float, damage: int) -> void:
    var space := get_world_2d().direct_space_state
    var query := PhysicsShapeQueryParameters2D.new()

    var circle := CircleShape2D.new()
    circle.radius = radius
    query.shape = circle
    query.transform = Transform2D(0.0, center)
    query.collision_mask = 0b0010  # Layer 2: Enemies

    var hits := space.intersect_shape(query)
    for hit in hits:
        var enemy: Node2D = hit.collider
        if enemy.has_method("take_damage"):
            enemy.take_damage(damage)

Ray Cast: Instant Hit Weapon

# Hitscan weapon (no projectile)
func fire_hitscan_weapon(from: Vector2, direction: Vector2, max_range: float) -> void:
    var space := get_world_2d().direct_space_state
    var query := PhysicsRayQueryParameters2D.create(from, from + direction * max_range)
    query.exclude = [self]
    query.collision_mask = 0b0010  # Enemies

    var result := space.intersect_ray(query)
    if result:
        var hit_enemy: Node2D = result.collider
        var hit_point: Vector2 = result.position

        spawn_hit_effect(hit_point)
        if hit_enemy.has_method("take_damage"):
            hit_enemy.take_damage(25)

Decision Tree: Collision Detection Methods

Use CaseMethodWhy
Continuous trigger zoneArea2D + signalsMemory of what's inside, signals are efficient
One-time pickup (coin)Area2D + queue_free() on enterSimple, automatic cleanup
Line-of-sight checkRayCast2DEfficient, built-in
Click-to-select unitsPhysicsPointQueryParameters2DSingle query, no permanent node
AOE spellPhysicsShapeQueryParameters2DOne-shot query, flexible shape
Instant-hit weaponPhysicsRayQueryParameters2DHitscan, no projectile physics
Platformer ground checkRayCast2D or raycast downPrecise ledge detection

Edge Cases

Collision During _ready()

# ❌ BAD: Raycasts don't work in _ready() (physics not initialized)
func _ready() -> void:
    if $RayCast2D.is_colliding():  # Always false!
        print("Hit something")

# ✅ GOOD: Wait for physics frame
func _ready() -> void:
    await get_tree().physics_frame
    if $RayCast2D.is_colliding():
        print("Hit something")

Area2D Not Detecting CharacterBody2D

# Problem: CharacterBody2D has collision_layer = 0 by default
# Solution: Explicitly set layer

# character.gd
func _ready() -> void:
    collision_layer = 0b0001  # Layer 1: Player

Raycast Hitting Backfaces

# Raycasts hit both front and back of collision shapes
# To raycast one-way (front only), use Area2D monitoring

Performance

# ✅ GOOD: Disable raycasts when not needed
func _ready() -> void:
    $OptionalRaycast.enabled = false

func check_vision() -> void:
    $OptionalRaycast.enabled = true
    $OptionalRaycast.force_raycast_update()
    var sees_player := $OptionalRaycast.is_colliding()
    $OptionalRaycast.enabled = false
    return sees_player

# ❌ BAD: Always-on raycasts for rarely-used checks
# Leave RayCast2D.enabled = true for vision checks once per second

Expert Techniques & Optimizations

1. Low-Level Servers for Massive Swarms

If you are dealing with tens of thousands of projectiles or physics objects, the SceneTree node overhead will bottleneck the CPU. Bypass the SceneTree entirely by using PhysicsServer2D and RenderingServer to create, move, and draw bodies directly in C++ or GDScript.

2. Physics Interpolation

If your game uses a low physics tick rate to save CPU cycles (causing visible jitter), enable Physics Interpolation in the Project Settings. This keeps the physics tick rate low but interpolates visual transforms smoothly over rendered frames.

3. Safe RigidBody2D Integration

extends RigidBody2D

var thrust := Vector2(0, -250)
var torque := 20000.0

# According to the RigidBody2D documentation, we must use _integrate_forces
# to safely modify physical state without fighting the physics server.
func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
    if Input.is_action_pressed("ui_up"):
        # Apply force taking current rotation into account
        state.apply_force(thrust.rotated(rotation))
    else:
        state.apply_force(Vector2.ZERO)

    var rotation_dir := Input.get_axis("ui_left", "ui_right")
    state.apply_torque(rotation_dir * torque)

Reference

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.08%
按下载量换算365

Claude

29.7%
按下载量换算318

Cursor

18.05%
按下载量换算193

Gemini CLI

9.84%
按下载量换算105

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限需确认

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills