Godot报错:尝试在空实例调用is_stopped函数,求解决方案
问题根源
报错本质是bulletCooldownNode变量为null,无法调用is_stopped()方法。核心原因是脚本设为全局后,节点树结构发生变化,原来的子节点引用失效。
排查与修复思路
检查全局脚本的加载方式
如果你把脚本设为自动加载(AutoLoad),对应的节点会独立于玩家场景存在,它的子树里没有BulletCooldownNode这个Timer节点。原来的@onready var bulletCooldownNode := $BulletCooldownNode是从当前节点的子树查找,自然返回null。
解决:要么把Timer节点添加到全局节点的子树中,要么改为从玩家实例中获取Timer(因为你导出了Player场景,实例化后的玩家节点才包含这个Timer)。验证节点引用的有效性
在_ready()函数中添加打印语句,确认bulletCooldownNode是否为null:func _ready(): print(bulletCooldownNode) # 输出null则说明引用失败修正Timer节点的引用路径
全局脚本应该从实例化的玩家对象中获取Timer,而不是自身节点。修改代码示例:extends CharacterBody2D @export var Player : PackedScene var Bullet = load("res://Scenes/Projectiles/player_bullet.tscn") var BigBullet = load("res://Scenes/Projectiles/player_bullet(BIG).tscn") var bulletCooldownNode: Timer = null var player_instance: CharacterBody2D = null @onready var starting_position = global_position func _ready(): # 实例化玩家并添加到场景 player_instance = Player.instantiate() add_child(player_instance) # 从玩家实例中获取Timer节点 bulletCooldownNode = player_instance.get_node("BulletCooldownNode") func get_input(): if player_instance == null or bulletCooldownNode == null: return look_at(get_global_mouse_position()) set_rotation_degrees(max(min(75, get_rotation_degrees()), -75)) if Input.is_action_pressed("Shoot") and bulletCooldownNode.is_stopped(): shoot()确认节点命名与路径正确性
检查玩家场景中的Timer节点名称是否确实为BulletCooldownNode,且没有被移动到其他子节点下(如果有,需要调整路径为$ParentNode/BulletCooldownNode)。重新评估脚本的全局必要性
如果发射逻辑仅和玩家绑定,没必要把整个玩家脚本设为全局。可以将全局需要的功能(比如发射方法)抽成单独的自动加载脚本,玩家节点仍作为场景实例存在,这样原来的子节点引用就能正常工作。
内容的提问来源于stack exchange,提问作者Parkster00

