tutorial_resources - seraph526/godot-se GitHub Wiki

资源

节点和资源

节点Node是Godot中十分重要的数据类型,引擎中的很多行为和功能都是通过它来实现的。但是,还有另外一种数据类型也非常重要。这就是资源Resource

节点专注于行为,如绘制一个精灵,绘制一个3D模型,物理,GUI Controls等等,资源仅仅是数据容器。就是说它们没有任何行为也不会处理任何信息。资源只是存储数据。

Texture, Script, Mesh, Animation, Sample, AudioStream, Font, Translation等等都是资源。

当Godot保存或读取(从磁盘)一个场景(.scn 或.xml),一张图片(png,jpg),一个脚本(.gd),诸如此类,这些文件被认为是资源。

当从磁盘加载一个资源,它通常只被加载一次*。如果有一个资源的副本已经被加载到内存中,尝试再次加载该资源将会近回相同的副本。这也说明了资源只是数据容器,所以不需要复制它们。

典型的,Godot中的每一个物体(节点,资源,或其他一些)能够导出属性,属性可以是多种类型(如strig,integer,Vector2等等),这些类型也可是资源。也就是说节点和资源可以包含资源做为属性。为了更直观的说明这点,见下图:

处部VS内置

资源作为属性可以有两种方式,外部external(文件存储在硬盘上)或者内置built-in。为了更精确的说明,如下所示,是精灵Sprite节点上的一张纹理图Texture:

点击右侧预览旁的">"按扭,允许查看和编辑资源属性。其中的一处属性(path)显示了它来自哪。这里,它来自一张png图片。

当资源来自一个文件,那么认为它是外部资源。如果路径(path)属性被清空(或者从一开始就没有path路径),则认为它是内置资源。

如,在上面的示例中,路径"res://robi.png"被清空了,之后保存场景,资源将被保存在.scn场景文件中,不再关联外部的"robi.png"文件。不管怎样,即使是存储为内置资源,场景被多次初始化,资源也只被加载一次。也就是说,不同的Robi robot场景初始化仍然是共享同一张图片资源。

从代码加载资源

从代码加载资源很简单,有两种方式。第一种是使用load(),如下:


func _ready():

        var res = load("res://robi.png") # resource is loaded when line is executed
        get_node("sprite").set_texture(res)

第二种方法更理想,但是参数只能是静态String变量,因为,它是在编译时加载资源的。


func _ready():

        var res = preload("res://robi.png") # resource is loaded at compile time
        get_node("sprite").set_texture(res)

加载场景

场景也是资源,有个地方需要注意。保存到磁盘的场景是一种打包形式的资源 PackedScene,就是说,场景是打包在一个资源中的。

要得到一个场景的实例,必须使用instance() 方法

func _on_shoot():

        var bullet = preload("res://bullet.scn").instance()
        add_child(bullet)                  

这个方法在层级中创建了一个节点,配置它们(设定所有的属性)并返回场景的根节点,它可以填加任意其他类型的节点。 这种几点优势。因为instance()函数执行是非常快的,填加额外的内容到场景效率非常高。新敌人,子弹,效果等等可以被快速的填加和删除,不必每次都从磁盘上加载它们。这一点非常重要,一定要记住,因为通常,图片,面片等等都是在多个场景实例间共享的。

冻结资源

资源继承自Reference。因此,当一个资源不身被使用时,它会自动释放。因为,大部分情况下。资源都是包含有节点,脚本或其他资源的,当节点被移除或释放时,所有的子资源也会被释放。

脚本

像Godot中的其他脚本一样,不只是节点,资源也可以通过脚本实现,但这也不算是件十分让人喜悦的事,因为资源仅仅是数据容器而已。