资源
节点和资源
Node 类, 因为它是您用来编码行为的类, 并且引擎的大多数功能都依赖于该类. 还有另一个同样重要的数据类型: Resource.
节点 为您提供功能: 它们绘制精灵, 3D模型, 模拟物理, 排列用户界面等. 资源 是 数据容器 . 它们自己不能做任何事情: 而是, 节点使用资源中包含的数据.
.tscn 或 .scn 文件), 图像, 脚本……这是一些 资源 示例: Texture, Script, Mesh, Animation, AudioStream, Font, Translation.
它只加载一次 . 如果该资源的副本已在内存中, 则每次尝试再次加载该资源将返回相同的副本. 由于资源只包含数据, 因此无需复制它们.
每个对象(无论是节点还是资源)都可以导出属性. 属性有很多类型, 例如String, integer, Vector2等, 并且任何这些类型都可以成为资源. 这意味着节点和资源都可以包含资源以作为属性:
外部与内置
有两种保存资源的方法. 它们是:
- 外部 , 对于场景, 作为单独文件保存在磁盘上.
- 内置 , 保存在”.tscn “或它们所附的”.scn “文件内.
Sprite 节点中的一个 Texture:
点击资源预览可以使我们查看和编辑资源的属性.
Path属性告诉我们资源来自何处. 在这里, 它来自一个叫robi.png的PNG图像. 当资源来自这样的文件时, 它属于外部资源. 如果您去掉这个路径或此路径为空, 则它将成为内置资源."res://robi.png"并保存,Godot会将图像保存在.tscn场景文件中. 注解 即使您保存一个内置资源, 当多次实例化一个场景时, 引擎也只会加载该场景的一个副本.从代码中加载资源
load()函数: GDScript C#func _ready(): var res = load("res://robi.png") # Godot loads the Resource when it reads the line. get_node("sprite").texture = res
public override void _Ready(){ var texture = (Texture)GD.Load("res://robi.png"); // Godot loads the Resource when it reads the line. var sprite = GetNode<Sprite>("sprite"); sprite.Texture = texture;}
预加载(preload)资源. 与load不同,preload会从硬盘中读取文件, 并在编译时加载它. 因此, 您不能使用一个变量化的路径调用预加载: 您需要使用常量字符串. GDScript C#func _ready(): var res = preload("res://robi.png") # Godot loads the resource at compile-time get_node("sprite").texture = res
// 'preload()' is unavailable in C Sharp.
加载场景
PackedScene 类型的资源. 该场景被打包在资源内部. PackedScene.instance() 方法. GDScript C#func _on_shoot(): var bullet = preload("res://bullet.tscn").instance() add_child(bullet)
此方法在场景的层次结构中创建节点, 对其进行配置, 然后返回场景的根节点. 然后, 您可以将其添加为任何其他节点的子级. PackedScene.instance() 函数速度相当快, 您可以创建新的敌人, 子弹, 效果等, 而无需每次都从磁盘再次加载它们. 请记住, 像往常一样, 图像, 网格等都是在场景实例之间共享的.private PackedScene _bulletScene = (PackedScene)GD.Load("res://bullet.tscn");public void OnShoot(){ Node bullet = _bulletScene.Instance(); AddChild(bullet);}
释放资源
资源(Resource)不再使用时, 它将自动释放自己. 由于在大多数情况下, 资源包含在节点中, 因此当您释放节点时, 如果没有其他节点使用该节点拥有的所有资源, 则引擎也会释放它们.创建自己的资源
*.tres,*.res)之间自由转换的能力. 它们还从Reference类型继承引用计数内存管理. Dictionary (JSON)或要解析的 File. 将资源区分开来的是它们对 Object, Reference, 和 Resource 功能的继承:
- 它们可以定义常量, 因此不需要其他数据字段或对象中的常量.
setter/getter方法. 这允许对基础数据进行抽象和封装. 如果资源脚本的结构需要更改, 则使用资源的游戏则不必更改.Resources可以触发对所管理数据更改的响应.- 它们具有已定义的属性, 因此用户知道其数据将100%存在.
- 资源自动序列化和反序列化是一个Godot引擎的内置功能. 用户无需实现自定义逻辑即可导入/导出资源文件的数据.
- 资源甚至可以递归地序列化子资源, 这意味着用户可以设计更复杂的数据结构.
*.tres). 导出游戏后,Godot将资源文件序列化为二进制文件(*.res), 以提高速度和压缩率.- Godot引擎的属性检查器开箱即用地渲染和编辑资源文件. 这样, 用户通常不需要实现自定义逻辑即可可视化或编辑其数据. 为此, 请在文件系统停靠面板中双击资源文件, 或在属性检查器中点击文件夹图标, 然后在对话框中打开该文件.
Resource之外的 其他 资源类型.资源(Resources)变得很容易.
资源(Resources)对象. 只要您的脚本扩展了该类型, 它甚至可以是派生资源(Resource)的类型.script属性设置为您的脚本.资源(Resource)脚本的自定义属性. 如果编辑这些值并保存资源, 则属性检查器也会序列化自定义属性!要从属性检查器中保存资源, 请点击属性检查器的工具菜单(右上角), 然后选择保存或另存为.... script classes, then it streamlines the process. Defining a name for your script alone will add it to the Inspector’s creation dialog. This will auto-add your script to the Resource object you create. 让我们看一些示例. GDScript C## bot_stats.gdextends Resourceexport(int) var healthexport(Resource) var sub_resourceexport(Array, String) var strings# Make sure that every parameter has a default value.# Otherwise, there will be problems with creating and editing# your resource via the inspector.func _init(p_health = 0, p_sub_resource = null, p_strings = []): health = p_health sub_resource = p_sub_resource strings = p_strings# bot.gdextends KinematicBodyexport(Resource) var statsfunc _ready(): # Uses an implicit, duck-typed interface for any 'health'-compatible resources. if stats: print(stats.health) # Prints '10'.
注解// BotStats.csusing System;using Godot;namespace ExampleProject { public class BotStats : Resource { [Export] public int Health { get; set; } [Export] public Resource SubResource { get; set; } [Export] public String[] Strings { get; set; } // Make sure that every parameter has a default value. // Otherwise, there will be problems with creating and editing // your resource via the inspector. public BotStats(int health = 0, Resource subResource = null, String[] strings = null) { Health = health; SubResource = subResource; Strings = strings ?? new String[0]; } }}// Bot.csusing System;using Godot;namespace ExampleProject { public class Bot : KinematicBody { [Export] public Resource Stats; public override void _Ready() { if (Stats != null && Stats is BotStats botStats) { GD.Print(botStats.Health); // Prints '10'. } } }}
资源(Resource)脚本类似于Unity的ScriptableObjects. 属性检查器为自定义资源提供内置支持. 如果需要的话, 用户甚至可以设计自己的基于控制(Control)的工具脚本, 并将它们与一个 EditorPlugin 结合起来, 以为他们的数据创建自定义的可视化和编辑器. 虚幻4引擎的数据表DataTables和CurveTable也很容易使用资源脚本重新创建. 数据表DataTables是映射到自定义结构的字符串, 类似于将字符串映射到辅助自定义资源脚本的字典. GDScript C## bot_stats_table.gdextends Resourceconst BotStats = preload("bot_stats.gd")var data = { "GodotBot": BotStats.new(10), # Creates instance with 10 health. "DifferentBot": BotStats.new(20) # A different one with 20 health.}func _init(): print(data)
using System;using Godot;public class BotStatsTable : Resource{ private Godot.Dictionary<String, BotStats> _stats = new Godot.Dictionary<String, BotStats>(); public BotStatsTable() { _stats["GodotBot"] = new BotStats(10); // Creates instance with 10 health. _stats["DifferentBot"] = new BotStats(20); // A different one with 20 health. GD.Print(_stats); }}
字典(Dictionary)值, 还可以选择…- 从电子表格导入值表并生成这些键值对, 或者…
资源(Resources)时, 将其添加到属性检查器中.CurveTables是相同的东西, 除了映射到一个浮点值数组或一个 Curve/ Curve2D 资源对象之外. 警告*.tres/*.res)将在文件中存储它们使用的脚本的路径. 加载后, 它们将获取并加载此脚本作为其类型的扩展. 这意味着尝试指定一个子类, 即脚本的内部类(例如在GDScript中使用class关键字)将不起作用.Godot将无法正确序列化脚本子类上的自定义属性.Node脚本, 并看到它没有扩展Resource, 然后判断脚本由于类型不兼容而无法为资源(Resource)对象加载. GDScript C#extends Nodeclass MyResource: extends Resource export var value = 5func _ready(): var my_res = MyResource.new() # This will NOT serialize the 'value' property. ResourceSaver.save("res://my_res.tres", my_res)
using System;using Godot;public class MyNode : Node{ public class MyResource : Resource { [Export] public int Value { get; set; } = 5; } public override void _Ready() { var res = new MyResource(); // This will NOT serialize the 'Value' property. ResourceSaver.Save("res://MyRes.tres", res); }}
