PhysicsDirectSpaceState2D.intersect_point
2026/4/14大约 3 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — PhysicsDirectSpaceState2D.intersect_point
PhysicsDirectSpaceState2D.intersect_point
定义
intersect_point 用来检测 2D 空间中某个点附近有哪些物理物体。不像射线那样只检测一条线,而是检测一个点周围"有没有东西"。
打个比方:射线检测就像手电筒照一条线,intersect_point 就像你用手指戳一个位置,看看那个位置上有什么东西。如果那个位置正好有一个碰撞体(比如角色、墙壁),就会返回它。
在实际游戏开发中,点检测常用于:检测玩家是否站在某个区域上、判断物品能否放置在指定位置、实现范围伤害(检测爆炸范围内的所有敌人)等。
函数签名
C#
public Godot.Collections.Array<Dictionary> IntersectPoint(PhysicsPointQueryParameters2D parameters, int maxResults = 32)GDScript
func intersect_point(parameters: PhysicsPointQueryParameters2D, max_results: int = 32) -> Array[Dictionary]参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
parameters | PhysicsPointQueryParameters2D | 是 | 查询参数,包含检测位置、碰撞掩码等 |
maxResults | int | 否 | 最多返回几个结果,默认 32 |
PhysicsPointQueryParameters2D 常用属性
| 属性 | 类型 | 说明 |
|---|---|---|
Position / position | Vector2 | 要检测的点位置 |
CollisionMask / collision_mask | int | 碰撞层掩码 |
Exclude / exclude | Array | 排除的物体列表 |
返回值
Array[Dictionary] —— 返回一个数组,数组中每个元素都是一个碰撞结果的字典(包含 collider、collider_id、rid 等键)。如果该点没有碰到任何物体,返回空数组。
代码示例
基础用法:检测某个位置是否有物体
C#
using Godot;
public partial class PointQueryTest : Node2D
{
public override void _PhysicsProcess(double delta)
{
var spaceState = GetWorld2D().DirectSpaceState;
var query = new PhysicsPointQueryParameters2D();
query.Position = GlobalPosition;
var results = spaceState.IntersectPoint(query);
foreach (var result in results)
{
GD.Print($"该位置有物体:{result["collider"]}");
// 运行结果: 打印当前位置上所有物体的名称
}
}
}GDScript
extends Node2D
func _physics_process(delta):
var space_state = get_world_2d().direct_space_state
var query = PhysicsPointQueryParameters2D.new()
query.position = global_position
var results = space_state.intersect_point(query)
for result in results:
print("该位置有物体:%s" % result["collider"])
# 运行结果: 打印当前位置上所有物体的名称实际场景:检测爆炸范围内的所有敌人
C#
using Godot;
public partial class Explosion : Area2D
{
[Export] public float ExDamage = 50.0f;
public void Explode(Vector2 center)
{
GlobalPosition = center;
var spaceState = GetWorld2D().DirectSpaceState;
var query = new PhysicsPointQueryParameters2D();
query.Position = center;
query.CollisionMask = 2; // 敌人层
var results = spaceState.IntersectPoint(query, 32);
foreach (var result in results)
{
var collider = result["collider"].AsGodotObject();
if (collider.HasMethod("TakeDamage"))
{
collider.Call("TakeDamage", ExDamage);
}
}
GD.Print($"爆炸命中 {results.Count} 个敌人");
// 运行结果: 对范围内所有敌人造成伤害
}
}GDScript
extends Area2D
@export var damage: float = 50.0
func explode(center: Vector2):
global_position = center
var space_state = get_world_2d().direct_space_state
var query = PhysicsPointQueryParameters2D.new()
query.position = center
query.collision_mask = 2 # 敌人层
var results = space_state.intersect_point(query, 32)
for result in results:
var collider = result["collider"]
if collider.has_method("take_damage"):
collider.take_damage(damage)
print("爆炸命中 %d 个敌人" % results.size())
# 运行结果: 对范围内所有敌人造成伤害进阶用法:检测是否能放置建筑
C#
using Godot;
public partial class PlacementChecker : Node2D
{
[Export] public Vector2 ExBuildingSize = new(64, 64);
public bool CanPlaceAt(Vector2 position)
{
var spaceState = GetWorld2D().DirectSpaceState;
var query = new PhysicsPointQueryParameters2D();
query.Position = position;
query.CollisionMask = 1; // 地面/障碍物层
var results = spaceState.IntersectPoint(query);
bool canPlace = results.Count == 0;
GD.Print($"位置 {position} {(canPlace ? "可以" : "不可以")}放置建筑");
// 运行结果: 该位置没有障碍物时可以放置
return canPlace;
}
}GDScript
extends Node2D
@export var building_size: Vector2 = Vector2(64, 64)
func can_place_at(position: Vector2) -> bool:
var space_state = get_world_2d().direct_space_state
var query = PhysicsPointQueryParameters2D.new()
query.position = position
query.collision_mask = 1 # 地面/障碍物层
var results = space_state.intersect_point(query)
var can_place = results.is_empty()
print("位置 %s %s放置建筑" % [position, "可以" if can_place else "不可以"])
# 运行结果: 该位置没有障碍物时可以放置
return can_place注意事项
- 检测的是点,不是范围:
intersect_point只检测一个精确的数学点。如果需要检测圆形或矩形范围,应该使用intersect_shape。 - 可能返回多个结果:如果多个物体重叠在同一位置,会返回多个结果。
- 碰撞体必须包含该点:只有当碰撞体的形状确实包含该检测点时才会被返回。
- 推荐在
_PhysicsProcess中调用:确保物理世界状态是最新的。
