Godot GDScript中timer变量赋值0后无法归零问题咨询
Godot timer变量无法重置归零问题
问题复现代码
extends Node onready var box_container: BoxContainer = $VBoxContainer var stage = 0 setget on_stage_change var timer = 0.0 func on_stage_change(new_value): if new_value > 5: stage = 5 else: stage = new_value func _process(delta): if stage > 5: return var file: Dictionary = loadjson() handle_message(file, timer) if timer == 0.0: print("corrent") timer += delta func handle_message(file: Dictionary, timer: float): var json = file[String(stage)] if json["sender"] == "system": add_system_message(json["message"]) elif json["sender"] == "boss": add_boss_message(json["message"], timer) print(timer) # 输出值 > 1 else: print("currently not handled") func add_boss_message(message: String, timer: float): var current_label = box_container.get_child(box_container.get_child_count()-1) if is_most_recent_message_typing() and timer > 1: current_label.text = message stage += 1 timer = 0.0 print(timer) # 此处输出值为0 elif not is_most_recent_message_typing(): var label = Label.new() label.modulate = Color(1, 0, 0) label.text = "[typing]" box_container.add_child(label) print(timer) # 此处输出值为0 func is_most_recent_message_typing(): if box_container.get_child(box_container.get_child_count()-1).text == "[typing]": return true return false func loadjson(): var file: File = File.new() file.open("Messages.json", File.READ) var json_file = parse_json(file.get_as_text()) return json_file func add_system_message(message: String): var label = Label.new() label.text = message label.modulate = Color(1, 0, 0) box_container.add_child(label) stage += 1
问题现象
使用Steam平台发布的最新稳定版Godot引擎开发时,遇到timer变量始终无法归零的异常:跟踪程序执行流程确认,在add_boss_message方法中执行timer = 0.0赋值时,该位置打印的timer值确实为0,但方法执行完毕后timer值会重新变为大于1的数值,_process生命周期中始终无法触发timer == 0.0的判断逻辑。
根本原因
GDScript中float、int这类基础数据类型采用值传递规则,不是引用传递。
你在handle_message、add_boss_message的参数列表里定义的名为timer的参数,和脚本顶层定义的成员变量timer完全是两个独立的变量:
- 调用
handle_message(file, timer)时,只是把当前成员变量timer的数值拷贝了一份传给函数,函数内部操作的是拷贝出来的局部变量 - 你在
add_boss_message里赋值timer = 0.0,修改的只是函数内部的局部拷贝,根本没碰到外层的成员变量timer,所以函数退出后局部变量销毁,外层的成员变量还是原来累加的数值,自然不会归零。
修复方法
两种改法二选一即可:
- 去掉
handle_message、add_boss_message参数列表里的同名timer参数,函数内部直接操作顶层的成员变量timer - 如果要保留参数传递逻辑,针对基础类型需要把修改后的值return回来,在外层接收返回值重新赋值给成员变量。
注意:只有Object派生类的实例(比如节点、资源这类)在GDScript里是引用传递,传参后修改内部属性会影响原对象,基础数值类型、字符串、字典、数组在传参时默认都是值传递(字典、数组如果需要深拷贝还要手动调用
duplicate()方法)。
内容的提问来源于stack exchange,提问作者Who Cares
相关产品推荐
相关产品推荐

