房间和入口的第一步

房间管理器

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

房间转换

This conversion must take place every time you want to activate the system. It does not store the room graph in your project (for flexibility and to save memory). You can either trigger it by pressing the Convert Rooms button in the editor toolbar (which also has a keyboard shortcut) or by calling the rooms_convert() method in the RoomManager. The latter method will be what you use in-game. Note that for safety, best practice is to call rooms_clear() before unloading or changing levels.

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

If you convert the level while the editor is running, the portal culling system will take over from the normal Godot frustum culling, potentially interfering with editor features. To get around this, you can turn portal culling on and off using either the View Portal Culling toggle in the View menu on the editor toolbar (which also has a keyboard shortcut) or the Active setting in the RoomManager node.

备注

To use the RoomManager, you have to tell it where the rooms are in your scene tree, or, more specifically, where the RoomList node is. This RoomList is the parent of your rooms - see below. If the RoomList is not set, conversion will fail, and you will see a warning dialog box.

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

房间列表

Before we create any rooms, we must first create a node to be the parent of all the static objects, rooms, roomgroups, and so on in our level. This node is referred to as the the RoomList.

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

备注

The roomlist is not a special node type – it can just be a regular Spatial.

You will need to assign the roomlist node in the RoomManager so that it knows where to find the rooms.

Why do we use a specific branch of the scene tree and not the scene root? The answer is that there are many internal details of the system which are easier to manage if the rooms are placed on their own branch.

Often you will end up completely replacing the roomlist branch at runtime in your game as you load and unload levels.

房间

什么是房间?

Rooms are a way of spatially partitioning your level into areas that make sense in terms of level design. Rooms often quite literally are rooms (like in a building). Ultimately though, as far as the engine is concerned, a room represents a non-overlapping convex volume in which you typically place most of your objects that fall within that area.

A room doesn't need to correspond to a literal room. It could, for example, also be a canyon in an outdoor area or a smaller part of a concave room. With a little imagination, you can use the system in almost any scenario.

为什么要凸起?

Rooms are defined as convex volumes (or convex hulls) because it's trivial to mathematically determine whether a point is within a convex hull. A simple plane check will tell you the distance of a point from a plane. If a point is behind all the planes bounding the convex hull, then by definition it is inside the room. This makes all kinds of things easier in the internals of the system, such as checking which room a camera is within.

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

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

为什么是不重叠的?

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

If you accidentally create overlapping rooms, the editor will warn you when you convert the rooms, indicating any overlapping zones in red.

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

The system does attempt to cope with overlapping rooms as best as possible by making the current room "sticky". Each object remembers which room it was in during the previous frame and stays within it as long as it does not move outside the convex hull room bound. This can result in some hysteresis in these overlapping zones.

There is one exception, however, for internal rooms. You do not have to worry about these to start with.

如何创建房间?

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

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

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

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

  2. Manually edit the points that define the convex hull in the room inspector or drag the points around using the editor gizmo (see 编辑房间点).

  3. Provide a manual bound. This is a MeshInstance in the room that has geometry in the shape of the desired bound, with a name with the postfix -bound. This is something you might choose to do if you create your levels in Blender or similar (see 在 Blender 中创建房间系统(或者其他建模工具)).

While the first option can be all that is required, particularly with simple rooms or for pre-production, using manual bounds gives you ultimate control at the expense of a small amount of editing. You can also combine the two approaches, perhaps using automatic bounds for most rooms but manually editing problem areas.

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

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

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

入口

If you create some rooms, place objects within them, then convert the level in the editor, you will see the objects in the rooms appearing and showing as you move between rooms. There is one problem, however! Although you can see the objects within the room that the camera is in, you can't see to any neighbouring rooms! For that we need portals.

Portals are special convex polygons that you position over the openings between rooms in order to allow the system to see between them. You can create a portal node directly in the editor. The default portal has 4 points and behaves much like a plane MeshInstance. You can add or remove points using the inspector. A portal requires at least 3 points to work - this is because it needs to form a polygon rather than a point or line.

To save editing effort, only one Portal is required between each pair of Rooms. You do not need to (and indeed should not) create two Portals that overlap in opposite directions. Portals default to being two-way, but you can make them one-way in the Portal inspector.

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

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

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

入口链接

There are two ways to specify which room the portal should link to:

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

  • Explicitly specify the room by setting the Linked Room in the inspector.

备注

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

试一试

By now you should be able to create a couple of rooms, add some nodes such as MeshInstances within the rooms, and add a portal between the rooms. Try converting the rooms in the editor and see if you can now view the objects in neighbouring rooms through the portal.

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

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

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