本文内容
第20章 为游戏世界添加物理
第20章 为游戏世界添加物理
介绍
前面的章节已经创建了一个 chicken 控制器。我们的鸡可以跑来跑去,但就在那里。有一个明显的缺陷。鸡不会与任何对象碰撞,并且不受重力影响。虽然我们可以在以下示例中使用 AddVelocity 轻松添加重力,但这还不够。
Physics::CharacterRequestBus::Event(GetEntityId(),
&Physics::CharacterRequestBus::Events::AddVelocity, m_gravity);
我们的关卡中没有任何物理对象,因此鸡不会撞到任何东西。它只会从地板上掉下来,被遗忘。本章将通过执行以下作来解决这个问题:
- 使用静态物理碰撞器构建足球场。
- 为 “O3DE” 模型的 3D 文本添加静态网格碰撞器。
- 使用刚体构建足球。
- 打开鸡的重力。
注意:本章的随附资源可以在 GitHub 上找到,网址为: https://github.com/AMZN-Olex/O3DEBookCode2111/tree/ch20_physical_world
创建足球场
图 20.1.足球场
我们可以通过调整盒子的大小并在其上添加静态物理碰撞器来构建一个开箱即用的足球场。 下面是足球场的实体轮廓。
图 20.2.足球场实体
Side 和 Ground 实体具有相同的结构,但具有不同的比例。
图 20.3.Side Entity 的组件
它们具有以下组件:
- Transform 组件以定位零件。
- “非均匀缩放”(Nonuniform Scale) 组件,将零件尺寸调整为所需尺寸
图 20.4. Non-uniform Scale 组件
- Mesh 组件,其盒体模型由 Non-uniform Scale 组件调整大小。
- PhysX Collider 组件,用于添加静态不可移动物理形状以匹配缩放的网格。
图 20.5.PhysX Collider Mesh (PhysX 碰撞器网格资产)
注意:无需缩放 PhysX Collider (PhysX 碰撞器) 的值,因为它们将由 Non-uniform Scale (非均匀缩放) 组件进行缩放。
在建造足球场时,我注意到在每一侧都有构建球门线的实体模式。因此,为了省去精力,我从一侧创建了一个预制件,将其复制并移动到足球场的另一端。
图 20.6.作为预制件的 Soccer Field的部件
在它们内部,有更多与 Side 和 Ground 实体具有相似设计的实体。
图 20.7. Goal_End.prefab
有三个缩放的框用于创建球门线和场地的边缘。
图 20.8.Goal_End形状
添加静态网格碰撞器
一个更有趣的问题是如何将物理碰撞器添加到 “O3DE” 的 3D 文本中。
图 20.9.3D 文本:O3DE
我在 Blender 中创建了这个模型并将其导出为 .FBX 文件添加到项目中,但这不会自动为我们提供物理形状。我们可以使用以下工具生成一个。
- 打开 Asset Browser。
- 找到 o3de.fbx 资产。
- 右键单击 o3de.fbx 并选择 Edit Settings。
- 这将打开 Fbx 设置对话框,选择 PhysX 选项卡。
- 在 PhysX Mesh (PhysX 网格) 组下,打开 Select mesh (选择网格)。
- 启用 Mesh 节点 Text_1。单击 Select 以保存选择。
- 单击 Update (更新) 以使用网格节点生成 PhysX Text_1形状。
- 资源浏览器应在 o3de.fbx 下显示 o3de.pxmesh。
- 返回到具有 O3DE 3D 文本的实体。
- 在其 PhysX Collider (PhysX 碰撞器) 组件上,将 Shape type (形状类型) 分配给 PhysicsAsset。
- 将 PhysX Mesh 分配给 o3de.pxmesh。
通过这些更改,您应该会看到 3D 文本上形成三角形。这是文本上物理网格的轮廓。文本已经变成了实体的。
图 20.10.O3DE 物理网格
添加足球
到目前为止,我们为足球场添加的所有形状都是不可移动的静态形状,但足球需要是动态的才能移动,因为鸡会踢来踢去。为此,我们需要 Physx Rigid Body (Physx 刚体) 组件。
图 20.11.球组件
PhysX Rigid Body (PhysX 刚体) 组件上的默认值将按原样工作。将 PhysX Collider (PhysX 碰撞器) 设置为半径为 0.5 的 Sphere (球体) 形状
图 20.12.球形
这将匹配引擎附带_spheres_1x1网格的大小。
图 20.13.球网
如果将此 Ball 实体放在足球场顶部,则会看到它掉落、与静态形状碰撞并滚动。
图 20.14.足球
注意:您可能会注意到,将鸡跑入球中不会移动球。使用 PhysX 角色控制器移动鸡。我们需要对物理触发器进行一些额外的工作,以检测碰撞并将脉冲应用于足球。这将在第 24 章 踢球 中完成。
小结
我们为鸡创造了一个物理世界。现在,我们可以通过对 AddVelocity 的附加调用来更新 ProcessInput 方法,从而将重力应用于鸡。
void ChickenControllerComponent::ProcessInput(const ChickenInput& input)
{
...
Physics::CharacterRequestBus::Event(GetEntityId(),
&Physics::CharacterRequestBus::Events::AddVelocity,
AZ::Vector3::CreateAxisZ(m_gravity));
}
注意:本章随附的源代码和资源可以在 GitHub 上找到: https://github.com/AMZN-Olex/O3DEBookCode2111/tree/ch20_physical_world