房间和入口的第一步

房间管理器

你想使用入口系统时,都需要在场景树中包含特殊的节点,叫做 RoomManager。RoomManager 负责系统的运行维护,特别是将你的房间中的对象转换为房间图,在运行时用于进行遮挡剔除和其他任务。

房间转换

每次要激活系统时都必须进行此转换。它不会在项目中存储房间图(为了灵活性和节省内存)。您可以通过按下编辑器工具栏中的转换房间按钮来触发它,另外有一个键盘快捷键,或者可以调用 RoomManager 中的 rooms_convert() 方法。后一种方法在你的游戏中使用。请注意,为了安全起见,最佳做法是在卸载或更改关卡之前调用 rooms_clear()

../../../_images/convert_rooms_button.png

如果你在编辑器运行时转换关卡,入口剔除系统将取代正常的 Godot 视锥剔除。这可能会影响一些编辑器的功能。因此,你可以使用编辑器工具栏上的视图菜单中的查看入口剔除切换,或者通过 RoomManager 节点中的 Active 设置来打开和关闭入口剔除。

注解

要使用 RoomManager,你必须给它告知房间在场景树中的位置,或者说 RoomList 节点的位置。这个 RoomList 是房间的父节点——见下文。如果没有设置 RoomList,转换将失败,你将收到一个警告对话框。

../../../_images/room_manager.png

房间列表

在我们创建任意房间之前,必须首先创建一个节点,作为我们关卡中所有静态对象、房间、房间组等的父节点。这个节点称为 RoomList

../../../_images/roomlist_node.png

注解

房间列表不是的特殊节点类型,它可以是普通的空间节点。

你需要在 RoomManager 中指定房间列表节点,这样 RoomManager 就知道可以在哪里找到房间。

为什么我们要使用场景树的一个特定分支,而不是使用场景的根节点?答案是,如果房间被放在自己的分支上,系统的许多内部细节就更容易管理。

通常,当你加载和卸载关卡时,你最终会在游戏运行时完全替换房间列表分支。

房间

什么是房间?

Room是一种将关卡空间划分为区域的方式,在关卡设计方面是有意义的。房间往往从字面上看 房间,例如建筑物。然而,就引擎而言,房间表示不重叠的凸面体,你通常会在其中放置大部分属于该区域的物体。

房间不需要对应字面上的房间。比如,它也可以是户外的一个峡谷,或一个凹形房间的较小部分。只要有想象力,你几乎可在任何场景下使用这个系统。

为什么要凸起?

房间之所以被定义为凸体,是因为在数学上,确定点是否在凸体之内非常容易。简单的平面检查,就能获得点与平面的距离。如果一个点在所有包围凸体外壳的平面之后,那么根据定义,它就在房间内。这使得系统内部各种事项变得更加容易,比如检查相机在哪个房间内。

凸体。定义为一系列朝外的平面。如果一个点在所有平面之后,点就在凸体之内。

../../../_images/convex_hull.png

为什么是不重叠的?

如果两个房间重叠,而相机或玩家在这个重叠区域,那么就没有办法知道这个物体应该在哪个房间,或者在哪个房间渲染。对于房间是非重叠的这一要求,的确对于关卡设计有影响。

如果你不小心创建了重叠的房间,编辑器会在你转换房间时标出警告,并以红色显示所有重叠的区域。

../../../_images/room_overlap.png

该系统试图通过使当前房间 “粘性 “ 来尽可能地应对重叠房间。每个物体都会记住它上一帧所在的房间,只要它不移动到凸体房间的范围之外,就会留在这个房间里。这可能会导致这些重叠区域出现一些延迟现象。

但是有一个例外内部房间 internal rooms ,就不必担心这些。

如何创建房间?

Room 是一种节点类型,可以像其他类型一样添加到场景树。将对象添加为 Room 节点的子级,以放置在房间内。

如何定义房间凸体的形状和位置?

因为定义房间边界是系统最重要的方面,因此在 Godot 提供三种方法来定义房间的形状:

  1. 使用房间内包含的物体的几何形状来自动创建一个近似的边界。

  2. 通过在房间检查器中手动编辑定义凸体的点,或使用编辑器辅助工具拖动这些点,参阅 编辑房间点

  3. 提供手动绑定。这是房间中的网络实例,具有所需范围形状的几何体,名称带有后缀 -bound 。如果您在 Blender 或类似软件中创建关卡,可能会选择这样做,参阅 在 Blender 中创建房间系统(或者其他建模工具)

虽然第一项选择可以满足所有需要,特别是简单的房间,或者预制,手动边界的更强功能提供了完全控制。也可以将这两种方法结合起来,或许可以大多数房间使用自动边界,对问题区域手动编辑。

只要未提供手动绑定,就会使用自动方法。

一对简单的房间。入口边缘以半透明红色显示,房间外体以绿色线框显示。

../../../_images/simple_room.png

入口

如果您创建一些房间,在其中放置对象,然后在编辑器中转换关卡,您将在房间之间移动时,能看到房间中的对象出现和显示。然而有一个问题!虽然您可以看到摄像机所在房间内的物体,但看不到任何相邻的房间!为此,需要有入口。

入口 Portal 是特殊的凸形多边形。你将其定位在房间之间的开口处,以便让系统看到房间之间的情况。你可以在编辑器中直接创建入口节点。默认的入口有 4 个点,其行为很像平面 plane MeshInstance。可以使用检查器添加或删除点。一个入口至少需要 3 个点,这是因为它需要形成多边形而不仅是点或线。

为了节省编辑工作,每对房间之间只须一个入口。你不需要也不应该创建两个重叠且相对的入口。入口默认是双向的,但您可以在入口设置中把它们变成单向。

因此,你应该在每一对相邻房间中只放置一个入口,这就是入口的“源房间” 。一般来说,你选择哪个房间作为源房间并不重要。入口的法线(表示为控制器的箭头)应该从源房间朝

../../../_images/portal_inspector.png

不要被这个箭头所迷惑。虽然箭头显示了入口的方向,但大多数入口都是双向的,从两个方向都可以看到。箭头更为重要是确保入口连接到正确的邻近房间。

入口链接

有两个选项用于指定入口应链接到哪个房间。

  • 将检查器中的 Linked Room 留空。在转换过程中,系统将尝试把入口自动链接到相邻最近的房间。这在大多数情况下能正常工作。

  • 您可以通过在检查器中设置 Linked Room 来明确指定房间。

注解

入口由一组 2D 点来定义。这确保所形成的多边形位于单个平面中,而入口的朝向由变换确定。这些点必须形成多边形。通过验证,忽略任何不能形成凸面形状的点。这使得编辑更容易,同时更难破坏系统。

试一试

现在您应该能够创建几个房间,在房间内添加一些节点,例如 MeshInstances,并在房间之间添加一个入口。尝试在编辑器中转换房间,看看您现在是否可以通过入口看到相邻房间中的对象。

../../../_images/simple_scenetree.png

您现在已经掌握了系统的基本原理。

下一步是查看可以由系统管理的不同类型的对象。