how this error happen?

Godot Version

4.3

Question

E 0:00:02:0335 void Player._Process(double): System.NullReferenceException: Object reference not set to an instance of an object.
<C# 错误> System.NullReferenceException
<C# 源文件> Player.cs:43 @ void Player._Process(double)
<栈追踪> Player.cs:43 @ void Player._Process(double)
Node.cs:2395 @ bool Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
CanvasItem.cs:1505 @ bool Godot.CanvasItem.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
Node2D.cs:546 @ bool Godot.Node2D.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
Sprite2D.cs:504 @ bool Godot.Sprite2D.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
Player_ScriptMethods.generated.cs:48 @ bool Player.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_variant_call_error*, Godot.NativeInterop.godot_variant*)

Hello, @xf960712! So, you can explain your question? Please, show a problem part of your C# code.

Player.cs:43 @ void Player._Process(double) 这里出现了空指针引用

新创的账号 我提问的时候说帐号要审核一段时间 没想到问题直接发布出来了 :rofl:

using Godot;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public partial class MainScene : Node2D
{
	AudioStreamPlayer player = new();
	AudioStreamPlayer player1 = new();
	Dictionary<string,AudioStream> audiomapper= new();
	Dictionary<string, AudioStream> audiomapper1 = new();
	public override void _Ready()
	{
		this.Set("SceneName", "MainScene");
		audiomapper["bullet1"] = GD.Load<AudioStream>("res://Audio/BU.mp3");
		audiomapper["bgm1"] = GD.Load<AudioStream>("res://Audio/BU.ogg");
		AddChild(player);
		audiomapper1["bullet1"] = GD.Load<AudioStream>("res://Audio/BU.mp3");
		audiomapper1["bgm1"] = GD.Load<AudioStream>("res://Audio/BU.ogg");
		AddChild(player1);
	} 
	public void PlayAudio(string name)
	{
		player.Stream = audiomapper[name];
		player.Play();
	}
	public void PlayAudio1(string name)
	{
		player1.Stream = audiomapper1[name];
		player1.Play();
	}
	public override void _Process(double delta)
	{
		
	}
}

上面是我的主场景脚本

using Godot;
using System;

public partial class Player : Sprite2D
{
	private double speed = 100;
	public PackedScene bulletPrefab;
	private MainScene Main_scene;
	public override void _Ready()
	{
		bulletPrefab = GD.Load<PackedScene>("res://Prefab/bullets.tscn");
		Main_scene = this.GetTree().CurrentScene as MainScene;
	}


	public override void _Process(double delta)
	{
		double movementdouble = speed * delta;
		float movement = (float)movementdouble;
		if (Input.IsActionPressed("ui_right"))
		{
			
			Position += new Vector2(movement, 0);
		}
		if (Input.IsActionPressed("ui_left"))
		{
			Position += new Vector2(-movement, 0);
		}
		if (Input.IsActionPressed("ui_up"))
		{
			 Position += new Vector2(0, -movement);
		}
		if (Input.IsActionPressed("ui_down"))
		{
			Position += new Vector2(0, movement);
		}
		if (Input.IsActionJustPressed("fire"))
		{
			Main_scene.PlayAudio1("bullets");
			var bullet = bulletPrefab.Instantiate() as Node2D;
			GetParent().AddChild(bullet);
			bullet.Position = Position;
			
		}

	}
}

我在Player类中想直接引用PlayAudio函数但Main_scene.PlayAudio1(“bullets”);这行报错了 我输出了下发现Main_scene是空的

Sry.Can u check the answer downbelow plz :smiling_face_with_three_hearts:

So, problem at this line:

Main_scene = this.GetTree().CurrentScene as MainScene;

I think, you can try to use that code instead:

Main_scene = GetNode<MainScene>("/root/YourRootNode");
# At '/root' path contains Window
# At '/root/YourRootNode' path contains a first node on scene
# So write your Node name with MainScene class after /root/
1 Like

If you need a more extensive explanation, please let us know. Also, if your question is resolved, please mark the post with the answer.

thx it works!

What is the difference between the two?

this.GetTree().CurrentScene

this one get the current scene instance that is running. why not work

Try using GD.print() to output the results from both options and compare them.
Edited: I tried to compare at my project and both results are the same, but apparently something is not quite right in your case. Still, I’m glad you did it.

yeah it shows 2 different results

<Node2D#33520878910>
<Node2D#28152169742>
Is there any way for me to know which Node each of these represents? XD

script = get_script()
script.get_global_name()
script.get_path()

1 Like

这个是gdscript的语法吗?

不是,只是告诉你有类似的方法。

Yes, @VeryUnHappyMan wrote how, but for C# it will look like this:

MainScene script = GetScript().As<MainScene>();
script.GetPath();
1 Like

我并没有在gdscript中尝试过这些,我自己使用时是在gdextension里面用的。

Object类的方法。
Variant get_script() const

返回该对象的 Script 实例,如果没有附加脚本,则返回 null。

Script类的方法。
StringNameget_global_name() const

要为脚本指定全局名称,你可以在 GDScript 中使用 class_name 关键字,在 C# 中使用 [GlobalClass] 属性。

2 Likes

好的 感谢!我后续查下文档看看