最后同步日期:2026-04-15 | Godot 官方原文 — Area2D
继承链:Node → CanvasItem → Node2D → Area2D
| 类型 | 名称 | 说明 |
|---|
| 属性 | Position | 本地位置(相对于父节点) |
| 属性 | GlobalPosition | 全局位置 |
| 属性 | Rotation | 旋转角度(弧度) |
| 属性 | Scale | 缩放比例 |
| 属性 | Skew | 倾斜角度(弧度) |
| 方法 | Rotate() | 旋转指定弧度 |
| 方法 | ToGlobal() | 本地坐标转全局坐标 |
| 方法 | ToLocal() | 全局坐标转本地坐标 |
| 类型 | 名称 | 说明 |
|---|
| 属性 | Visible | 是否可见 |
| 属性 | Modulate | 整体颜色叠加(乘法) |
| 属性 | SelfModulate | 自身颜色叠加(不影响子节点) |
| 属性 | ZIndex | 绘制层级(Z 轴排序) |
| 信号 | visibility_changed | 可见性变化时触发 |
| 方法 | GetGlobalMousePosition() | 获取鼠标全局坐标 |
| 类型 | 名称 | 说明 |
|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
一个看不见的"感应区"——它不会挡住任何东西,但能检测到有东西进来了、出去了、待在里面。
想象你房间门口装了一个自动感应灯——有人走过门口,灯就亮了;人走了,灯就灭了。Area2D 就是这个"感应器"。它不是物理体,所以东西可以穿过去(不会像墙壁一样挡住你),但它能感知到有什么东西经过了它。
使用频率:★★★★ 维度专用常用——非常常用,几乎所有游戏都会用到。
- 拾取物品(金币、血包、道具的拾取范围)
- 触发事件(走进某个区域触发剧情、播放动画)
- 伤害区域(爆炸范围、陷阱伤害区、毒气区)
- 检测区域(怪物"看到"玩家的视野范围)
- 安全区/危险区(离开安全区就会受伤)
- 金币拾取:玩家碰到金币的感应区就自动拾取
- 毒气伤害:玩家站在毒气区域内持续扣血
- 剧情触发:玩家走进某个区域触发对话
- 安全区判定:玩家在安全区内不会受到伤害
典型节点树:
Coin (Area2D)
├── CollisionShape2D
└── AnimatedSprite2D
| 资源 | 类型 | 说明 |
|---|
| 碰撞形状(如 CircleShape2D) | Shape2D 资源 | 赋给 CollisionShape2D 子节点,定义感应范围 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
Monitoring | bool | true | — | 是否监测其他物体进入/离开 |
Monitorable | bool | true | — | 是否能被其他 Area 监测到 |
Priority | int | 0 | — | 处理优先级(数字越大越先处理) |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
GravitySpaceOverride | 枚举 | Disabled | — | 重力覆盖模式:Disabled(禁用)/ Force(强制)/ Combine(叠加) |
GravityDirection | Vector2 | (0, 1) | — | 自定义重力方向 |
Gravity | float | 980.0 | — | 自定义重力强度 |
GravityPoint | bool | false | — | 重力是否指向某个点 |
GravityPointCenter | Vector2 | (0, 0) | — | 重力中心点坐标 |
GravityPointUnitDistance | float | 0.0 | — | 重力点衰减距离 |
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|
CollisionLayer | uint | 1 | CollisionObject2D | 所在碰撞层 |
CollisionMask | uint | 1 | CollisionObject2D | 检测哪些碰撞层 |
| 信号 | 触发时机 | 继承自 | 说明 |
|---|
body_entered(body) | 有物理体进入区域 | Area2D | 最常用的信号 |
body_exited(body) | 有物理体离开区域 | Area2D | — |
area_entered(area) | 有其他 Area 进入此区域 | Area2D | — |
area_exited(area) | 有其他 Area 离开此区域 | Area2D | — |
body_shape_entered(body_rid, body, body_shape_index, local_shape_index) | 碰撞形状进入 | Area2D | 更详细的碰撞信息 |
| 方法 | 返回值 | 说明 |
|---|
GetOverlappingBodies() | GodotArray[Node2D] | 获取当前区域内所有物理体 |
GetOverlappingAreas() | GodotArray[Area2D] | 获取当前区域内所有 Area |
HasOverlappingBodies() | bool | 区域内是否有物理体 |
HasOverlappingAreas() | bool | 区域内是否有 Area |
OverlapsBody(body) | bool | 指定物理体是否在区域内 |
OverlapsArea(area) | bool | 指定 Area 是否在区域内 |
GetOverlappingBodiesCount() | int | 区域内物理体数量 |
C
using Godot;
/// <summary>
/// 金币拾取区:玩家碰到金币区域时自动拾取
/// 节点结构:Coin (Area2D) + AnimatedSprite2D + CollisionShape2D
/// </summary>
public partial class Coin : Area2D
{
[Export] public int ExValue = 10; // 金币价值
[Signal] public delegate void CoinCollectedEventHandler(int value);
public override void _Ready()
{
// 连接信号:有物体进入这个区域时调用 OnBodyEntered
BodyEntered += OnBodyEntered;
}
private void OnBodyEntered(Node2D body)
{
// 检查进来的是不是玩家
if (body is CharacterBody2D)
{
// 发出拾取信号
EmitSignal(SignalName.CoinCollected, ExValue);
// 播放拾取音效等...
// 销毁金币自己
QueueFree();
}
}
}
/// <summary>
/// 伤害区域:站在里面会持续受伤(比如岩浆、毒气)
/// 节点结构:DamageZone (Area2D) + CollisionShape2D
/// </summary>
public partial class DamageZone : Area2D
{
[Export] public int ExDamagePerSecond = 20; // 每秒伤害
[Export] public float ExDamageInterval = 0.5f; // 伤害间隔(秒)
private Timer _damageTimer;
public override void _Ready()
{
_damageTimer = new Timer();
_damageTimer.WaitTime = ExDamageInterval;
_damageTimer.OneShot = false;
AddChild(_damageTimer);
BodyEntered += OnBodyEntered;
BodyExited += OnBodyExited;
}
private void OnBodyEntered(Node2D body)
{
// 有角色进入伤害区,开始持续造成伤害
if (body.HasMethod("TakeDamage"))
{
_damageTimer.Timeout += () => ApplyDamage(body);
_damageTimer.Start();
}
}
private void OnBodyExited(Node2D body)
{
// 角色离开伤害区,停止伤害
_damageTimer.Stop();
}
private void ApplyDamage(Node2D body)
{
body.Call("TakeDamage", ExDamagePerSecond * ExDamageInterval);
}
}
GDScript
# 金币拾取区:玩家碰到金币区域时自动拾取
# 节点结构:Coin (Area2D) + AnimatedSprite2D + CollisionShape2D
extends Area2D
@export var value: int = 10 # 金币价值
signal coin_collected(value: int)
func _ready() -> void:
# 连接信号:有物体进入这个区域时调用 _on_body_entered
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node2D) -> void:
# 检查进来的是不是玩家
if body is CharacterBody2D:
# 发出拾取信号
coin_collected.emit(value)
# 播放拾取音效等...
# 销毁金币自己
queue_free()
Area 和物理体的区别
| 对比项 | 物理体(Character/Rigid/Static) | Area |
|---|
| 会阻挡其他物体吗? | 会 | 不会 |
| 能被碰到弹开吗? | 能 | 不能 |
| 能检测进出吗? | 不能(除非用信号) | 能 |
| 适合做墙壁地板吗? | 适合 | 不适合 |
| 适合做拾取触发吗? | 不适合 | 适合 |