• godot编写一个节点实时属性显示系统


    我们在游戏开发中,为了方便,往往需要在游戏运行时获取到相关节点的信息

    如果我们每次都通过编辑器的debug模式看未免太过麻烦,所以会有在界面上显示一些节点属性值的需求。

    我们先梳理一下需求:

    1. 需要在运行时实时输出一些节点的关键属性信息(可以自定义哪些属性)
    2. 不同的场景可以配置不同的节点,且节点free掉后相应的信息显示可以消失(程序可控制何时显示哪个节点)

    实现思路

    1. 实时显示就是一个Label标签,每帧去请求特定节点的特定属性然后显示到Label上
    2. 为了让程序可以控制何时显示哪个节点,可以将节点和属性存到容器里,对外暴露接口,让游戏过程中能动态添加节点;然后每帧判断节点有没有被free掉,如果被free掉就删除节点

    核心代码

    新建一个场景,作为Debug的节点容器

    节点树结构如下:

    在这里插入图片描述

    顶层需要一个CanvasLayer类型,因为我们显示输出的地方要固定不变

    顶层下有一个Label标签,作为显示内容的载体

    Label标签可以设置下Margin边距,拓展策略长宽都选择Expand(拓展),这样内容长度较多时会自动撑开

    在这里插入图片描述

    最后在顶层挂一个脚本,代码如下:

    extends CanvasLayer
    
    export (NodePath) var node_path:NodePath      # 要显示的节点路径
    export (Array, String) var properties:Array   # 要显示的节点属性
    export (bool) var enabled:bool setget _set_enabled  # 是否启用debug
    
    var nodes:Dictionary = {}  # 存放所有需要输出的节点
    
    class NodeDebugInfo:  
    	var node:Node   # 节点
    	var props:Array # 节点属性
    
    func _ready(): 
    	add_by_path(node_path, properties) 
    	if enabled:
    		$Label.show()
    	else:
    		$Label.hide()
    	set_process(enabled)
    
    func _process(_delta):
    	debug()
    		
    func _set_enabled(val:bool):
    	enabled = val 
    	if val:
    		set_process(true)
    		$Label.show()
    	else:
    		set_process(false)
    		$Label.hide() 
    	 
    func add_by_node(node:Node, properties:Array) -> void:  
    	if !is_instance_valid(node):
    		return 
    	if !nodes.get(node.get_path()) == null:  
    		printerr("debug add duplicated node: ", node.get_path())  
    		return 
    	var debug_info = NodeDebugInfo.new()
    	debug_info.node = node 
    	for prop in properties:
    		if not prop in node:
    			printerr("no prop named '", prop, "' in ", node.get_path())
    			properties.erase(prop)
    			continue 
    	debug_info.props = properties 
    	nodes[node.get_path()] = debug_info
    	
    func add_by_path(path:NodePath, properties:Array) -> void:
    	var node = get_node(path) 
    	if is_instance_valid(node):
    		add_by_node(node, properties)
    
    func del_node(path:NodePath) -> void:
    	nodes.erase(path) 
    	
    func debug() -> void: 
    	var show_text:String = ""
    	for node_key in nodes.keys():
    		var info:NodeDebugInfo = nodes[node_key]
    		if is_instance_valid(info.node):
    			show_text += "%s:\n" % [info.node.get_path()]
    			show_text += "%s\n" % [_get_properties_output(info)] 
    			pass 
    		else:
    			nodes.erase(node_key) 
    	$Label.text = show_text
    			
    func _get_properties_output(info:NodeDebugInfo) -> String:
    	var out_str:String = ""
    	for prop in info.props:
    		out_str += "    %s : %s\n" % [prop, info.node[prop]]
    	return out_str
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    逻辑比较简单就不再赘述

    可以在编辑器指定一个固定的节点的部分属性来进行显示

    也可以在游戏内通过add_by_node(node:Node, properties:Array)/del_node(path:NodePath)两个接口动态添加/删除

    使用时将此scene挂载到相应场景,就可以获取它调用接口进行节点属性显示了。

    效果如下:

    在这里插入图片描述

  • 相关阅读:
    Ajax学习笔记
    python-tkinter-在文本框预设内容
    初步认识机器学习(Machine Leaning)
    Python Day13 面向对象基础【初级】
    机器学习训练,没有机器怎么办
    子路由的配置方法
    【MybatisPlus】MP的分页查询、多条件查询以及查询过程中解决null的空值判定
    使用vscode编辑markdown文件(可粘贴截图)
    微服务介绍
    金融统计学方法:神经网络
  • 原文地址:https://blog.csdn.net/qq_35621436/article/details/126218442