跳到主要内容

🎳物理系统简介

在项目开发中,有一个需求会经常出现,即检测两个物体何时相交,这被称为碰撞检测。在碰撞事件触发时进行一些处理,被称为碰撞响应。这些功能都是通过物理系统来实现的。

IdeaXR中提供了多种物理对象,每个物理对象都需要对应的碰撞形状用于进行碰撞检测。

note

在IdeaXR中,分为2D相关的对象和3D相关对象,此处以3D对象进行讲解,2D与之对应。

碰撞物体

IdeaXR中提供了四种扩展自CollisionObject的物体:

  • Area:Area节点提供检测功能,能够检测物体什么时候接触,并在物体进入或者离开时发出信号。同时也可以用来覆盖一些物理属性,比如重力。
  • StaticBody:该节点主要用于引擎中不移动的物体,会参与碰撞的检测,但不会因为碰撞而移动。
  • RigidBody:该节点实现了对3D物体的物理模拟,应当通过向其施加力的方式让其运动,其运动的结果是IdeaXR物理引擎计算的结果。
  • KinematicBody:该节点提供了碰撞检测,但没有提供物理响应。所有的物理响应(例如移动)需要在代码中自己写逻辑实现。

碰撞形状

碰撞物体可以包含任意数量的Shape对象作为子对象。这些形状用于定义对象的碰撞边界并检测与其他对象的接触。

note

为了碰撞检测,至少要为碰撞物体添加一个碰撞形状。

分配形状的最常用方法是添加CollisionShapeCollisionPolygon作为对象的子项。这些节点允许您直接在编辑器工作区中绘制形状。

caution

不要在编辑器中缩放碰撞形状。改变碰撞形状的大小时,你应该调整尺寸,而不是缩放。缩放形状可能会导致意外的碰撞行为。同样的,碰撞物体也尽可能的不进行缩放,而是通过调整碰撞形状尺寸的方式进行改变。

碰撞层级与遮罩

碰撞层系统是最强大但经常被误解的碰撞功能之一。该系统允许您在各种对象之间建立复杂的交互。关键概念是层(Layer)和遮罩(Mask)。每个CollisionObject都有20个不同的物理层可以相互作用,如下图: layer_and_mask

  • collision_layer: 表示该对象位于哪些层。默认情况下,所有实体都在层1上。
  • collision_mask: 表示该对象会对哪些层上的实体进行扫描。如果对象不在任何遮罩层中,则该实体将其忽略。默认情况下,所有实体都会扫描层1。

可以通过代码配置这些属性,也可以在“检查器”中对其进行编辑。

跟踪您正在使用每个图层的内容可能很困难,因此您可能会发现为您正在使用的层级指定名称很有用。可以在项目设置->层级名称中指定名称。 layer_and_mask

物理过程回调

物理引擎可能会产生多个线程以提高性能, 所以它能使用最多一个帧的时间来处理物理逻辑. 因此, 物体状态的变量的值, 如positionlinear velocity, 可能在当前帧不完全准确。

为了避免这种不准确性, 任何需要访问物体属性的代码都应该在 Node._physics_process() 回调中运行, 它在每个物理步骤之前以恒定的帧速率(默认为每秒60次)被调用. 一个 delta 参数会传递给这个方法, 这个参数是一个浮点数, 等于自上一步以来经过的时间(秒). 当使用默认的60Hz物理更新率时, 它通常等于 0.01666s。

note

建议在物理计算中使用delta参数, 以便当您更改物理更新速率或玩家设备跟不上时, 游戏能够正确运行。

物理材质

StaticBody和RigidBody可以被配置为使用物理材质。这允许调整一个物体的摩擦力和反弹力,并设置它是否具有吸收性、粗糙性。