tutorial_viewports - seraph526/godot-se GitHub Wiki

Viewports

###介绍 Godot有一个很小但很实用的功能叫视图。视图,就像它的名字一样,是一个矩形区域,世界场景会被绘制在这个矩形区域内。它的主要用途有三个,但它可以方便的适用于更多用途。所有的这些都是通过Viewport节点来实现的。

主要用途的一些问题如下: 场景根节点(Scene Root):被激活的场景根场景节点通常就是一个viewport。它是由用户创建用来显示场景上内容的。(通过阅读之前的章节你可以了解到这点) 子视图(Sub-Viewports): 当其为Control的子节点时,可以创建一个子视图 渲染目标(Render Target):视图可以被设置成”Render Target”模式。这种模式下,viewport在场景上不直接可见,但它的内容可以通过Texture来访问

###Input 视图可以向它的子节点传递和映射输入事件。Viewport和sub-subviewports都可以自动实现这一点,但是render target如果想要实现这个功能,需要通过Viewport.input 手动实现

###Listener Godot支持3D音效(2D和3D节点都可以实现此功能),更多介绍可以在另外一篇教程中找到[译者注:没找到作者说的这篇教程]。如果要让这种类型的声音节点可以被听到,需要将视图设置为lisener(2D或3D)。如果你是用的自定义的视图显示你的游戏场景,不要忘记将此设置打开。

Cameras (2D & 3D)

使用2D(Camera2D)或3D( Camera / Camera2D)摄像机时,摄像机会显示离它最近的父视图(viewport)的内容(层级向根节点方向),如下面的层级关系:

  • Viewport

    • Camera 此处,摄像机会显示其父级视图中的内容,但下面的节点关系中:
  • Camera

    • Viewport

它将不显示视图中的内容(如果有一个子场景,可能会显示根节点视图中的内容)

每个视图只允许有一个激活状态的摄像机。所以,如果当前如果有多个摄像机,要使用的摄像机一定要设置”current”属性,或通过脚本的方式设置:

camera.make_current()

Scale & Stretching

视图有个”rect”属性,X和Y属性通常不使用(只有根视图会真用到它们)。WIDTH和HEIGHT代替视图的大小,单位px。对于子视图,这些值会被父级的control重写。注意,如viewport设置为render targets,那么这里设置的则是分辨率。 可以通过缩放2D内容的方法使viewport的分辨率不同于在rect属性中设置的值,实现方法如下:

viewport.set_size_override(w,h) #custom size for 2D
viewport.set_size_override_stretch(true/false) #enable stretch for custom size

根视图的拉伸设置选项在项目设置中

Worlds

对于3D场景,视图要包含一个 World,这是3D世界链接物理和渲染的基础。Spatial-base节点将注册到最近的world中的视图节点中去。默认条件下,新创建的视图是不包括World的,它是使用与父视图相同的内容(根视却包含有一个world,它是被默认被渲染的物体)。可通过设置viewport属性的方法设置要一个World,这会分割这个视图的所有子节点与其父节点的视图世界的联系。这一功能在做场景介绍功能时特别有用。例如,你想要在场景中显示一个独立的人物形像到游戏中(就像Starscraft中的效果) 还有一种情况,如果想要让视图只显示单一物体,而不想创建world,可以使用视图的使用自身world的功能。当想要在2D场景中使用3D人物或物体时,这一功能非常有用。 对于2D场景,视图通常包含一个自身的 World2D。这通常能满足大部分做法,但当想要共享视图内容时,可以通地调用viewport api的方便来实现。

Capture

视图的内容是可以被捕捉到的。对于根视图而言,这是一个十分有效的截屏方式,调用api的方式如下:

# queues a screen capture, will not happen immediately
viewport.queue_screen_capture() 

在一到两帧之后(通过_process()检测),捕捉即可以被访问,通过以下的方式来调用:

var capture = viewport.get_screen_capture()

如果返回的图为空,说明捕捉还没有发生,稍等一会儿,因为这个api是异步的。

Sub-Viewport

如果视图为control的子节点,那么它将可以被激活并显示它包含的任何东西,结构如下:

  • Control
    • Viewport 视图将彻底的覆盖其父级control区域。

Render Target

要设置一个渲染对象,只要将视图的”render target”属性开启。开启后,节点下的任何内容都不会在场景编辑器中显示,要显示,一定要使用render target texture。可以通过以下的代码来访问:

var rtt = viewport.get_render_target_texture() 
sprite.set_texture(rtt)

默认情况下,当Render target在一个帧中被绘制时会被重新渲染。如果可见就会被渲染,否则不渲染。这一机制可以通过手动的方法设置为一次(once)或经常渲染(always),无论其当前是否可见。 在编辑器里已经有了一些类,在编辑器环境下,很多时候可以简化一些操作: