You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:27:14