Godot 4.x子弹发射失败:空引用异常问题求助(附C#代码)
问题:角色点击无法发射投射物,触发空引用异常
我正在制作一款游戏,希望让角色向敌人发射投射物,但点击后子弹无法发射,同时出现以下报错:
E 0:00:49:0157 PotatoCannon.cs:24 @ void PotatoCannon._PhysicsProcess(Double ): System.NullReferenceException: 对象引用未设置到对象的实例。
我的代码如下:
public partial class PotatoCannon : Sprite2D { public Timer cooldown; [Export] public PackedScene boolet { get; set; } public override void _Ready() { cooldown = GetNode<Timer>("CannonCooldown"); cooldown.Autostart = false; } public override void _PhysicsProcess(double delta) { GD.Print(cooldown.TimeLeft); LookAt(GetGlobalMousePosition()); RotationDegrees = Math.Abs(RotationDegrees); if (RotationDegrees % 360 >= 90.0 && RotationDegrees % 360 <= 270.0) { FlipV = true; } else { FlipV = false; } if (Input.IsActionJustPressed("shoot") && cooldown.TimeLeft == 0) { bullet Bullet = boolet.Instantiate<bullet>(); this.AddChild(Bullet); cooldown.WaitTime = 1; cooldown.Start(); } } }
问题定位与修复方案
1. 解决空引用异常
报错指向第24行的GD.Print(cooldown.TimeLeft);,说明cooldown变量未初始化,也就是GetNode<Timer>("CannonCooldown")没找到对应的节点。
- 检查节点结构:确认PotatoCannon节点下存在名为
CannonCooldown的Timer子节点,注意路径大小写敏感。 - 更可靠的绑定方式:改用
[Export]直接在编辑器绑定Timer,避免路径错误:
修改代码如下:[Export] public Timer cooldown; // 直接在Godot编辑器中将Timer节点拖入此字段 public override void _Ready() { cooldown.Autostart = false; // 保留这行,去掉_GetNode_的代码 }
2. 修复子弹无法发射的问题
- 确认
boolet已赋值:检查编辑器中是否为[Export] public PackedScene boolet绑定了子弹的PackedScene资源,否则实例化子弹时会触发空引用。 - 优化子弹生成逻辑:当前将子弹作为PotatoCannon的子节点,可能导致继承不必要的变换,建议调整:
if (Input.IsActionJustPressed("shoot") && cooldown.IsStopped) { bullet Bullet = boolet.Instantiate<bullet>(); GetParent().AddChild(Bullet); // 将子弹添加到父节点,避免跟随角色旋转 Bullet.GlobalPosition = GlobalPosition; // 设置初始位置为角色位置(可替换为炮口节点的GlobalPosition) Bullet.Rotation = Rotation; // 让子弹朝向瞄准方向 cooldown.WaitTime = 1; cooldown.Start(); } - 冷却判断优化:用
cooldown.IsStopped代替cooldown.TimeLeft == 0,避免浮点精度误差导致的判断失效。
内容的提问来源于stack exchange,提问作者Nanmuhong Ye
相关产品推荐
相关产品推荐

