Godot保存当前场景中所有的子节点的属性

Posted 张学徒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Godot保存当前场景中所有的子节点的属性相关的知识,希望对你有一定的参考价值。

Godot 3.4.4

我使用 Godot 制作应用程序所用到的功能,对一些需要用到的属性进行保存。

稍微修改也可以根据节点进行对一些游戏节点的数据的保存功能,思路都是一样的。

SAVE_PROPERTY_LIST 常量用于判断节点是否包含其中的属性,如果存在,则保存节点的这个属性的数据。

注意下面 _ready 方法里的 if child is Control: 做了只对 Control 进行保存的限制,删除即可对全部节点进行保存。

## 保存整个场景中的节点的信息
class_name SaveSceneControlNodeData
extends Node


## 要保存的属性(如果节点存在这个属性名,则保存这个数据)
const SAVE_PROPERTY_LIST : Array = ['text', 'pressed', "split_offset"]


# 树中的节点的数据
var _tree_node_data : Dictionary = 


var _directory : Directory = Directory.new()
var _file : File = File.new()


func _enter_tree():
	load_data()
	owner.connect("tree_exiting", self, "save_data")


func _ready():
	# 场景中的所有子节点在退出节点进行保存数据
	var list = []
	__all_children__(owner, list)
	for child in list:
		# 这里我限制了只对 Control 类型的节点的数据进行保存
		if child is Control:
			child.connect("tree_exiting", self, "__save_node_data__", [
				child, child.get_path(), _tree_node_data
			])


## 加载保存的数据
func load_data():
	var save_filename = get_save_filename()
	if _file.file_exists(save_filename):
		if _file.open(save_filename, File.READ) == OK:
			var content : String = _file.get_as_text()
			_file.close()
			
			var saved_data = parse_json(content)
			if saved_data:
				# 将属性设置到对应节点
				for path in saved_data:
					var node : Node = get_node(path)
					var p_data : Dictionary = saved_data[path]
					for property in p_data:
						node.set(property, p_data[property])
			
		else:
			print("打开 ", save_filename, " 文件失败")


## 保存数据
func save_data():
	var f = get_save_filename()
	print("准备保存文件:", f)
	if _file.open(f, File.WRITE) == OK:
		_file.store_string( to_json(_tree_node_data) )
		_file.close()
		print("保存 ", f, " 文件成功")
	else:
		print("保存失败")


## 获取保存的文件的路径
##(根据当前的场景路径,保存到这个场景的目录下,格式为:名称.json)
func get_save_filename():
	# 保存到的目录
	var save_to_path = owner.filename.get_base_dir()
	if not _directory.dir_exists(save_to_path):
		save_to_path = "res://"
	# 文件名
	var fname = owner.filename.get_file().get_basename()
	if fname == "":
		fname = 'scene_control_node_data'
	
	# 完整文件路径
	save_to_path = save_to_path.plus_file(fname) + '.json'
	return save_to_path


# 递归获取所有的节点
func __all_children__(parent: Node, list: Array):
	for child in parent.get_children():
		list.append(child)
	for child in parent.get_children():
		__all_children__(child, list)


# 记录这个节点的数据
func __save_node_data__(node: Node, node_path: NodePath, data: Dictionary):
	# 获取这个节点中包含的属性的数据
	var current_data = 
	for property in SAVE_PROPERTY_LIST:
		if property in node:
			current_data[property] = node[property]
	
	if current_data.size() > 0:
		# 根据节点路径记录数据
		data[node_path] = current_data

添加节点到场景中,默认节点都是没有任何内容的,运行后修改节点的属性,然后关闭再打开,即可看到节点存在了内容,对制作应用程序来说很方便。

以上是关于Godot保存当前场景中所有的子节点的属性的主要内容,如果未能解决你的问题,请参考以下文章

Godot保存当前场景中所有的子节点的属性

信号-计时器例子

Godot通过属性检查器显示对应节点的脚本属性

使用 EF Core 保存附加实体时如何删除子实体

Godot节点的 ready init enter_tree process 方法执行顺序

Godot相机抖动