Access to the properties of the Node to which the script is attached (Godot 4, C#)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By slavi

Script is attached to “TextureRect” node, how can I access “Texture” property?

using Godot;
using System;

public partial class SlotHandler : Node
{
	[Export]
	Texture2D tex1, tex2;

	public override void _Ready()
	{
		this.Connect("gui_input", new Callable(this, nameof(GuiInput)));
	}

	public void GuiInput(InputEvent inputEvent)
	{
		if(inputEvent is InputEventMouseButton)
		{
			if((inputEvent as InputEventMouseButton).ButtonIndex == MouseButton.Left)
			{
				if ((inputEvent as InputEventMouseButton).Pressed == true) Texture = tex2;
				if ((inputEvent as InputEventMouseButton).Pressed == false) Texture = tex1;
			}
		}
	}
}

The problem is in lines “Texture = tex1;” and “Texture = tex2;”
I tried option “this.Texture = tex1;”, that doesn’t work

How to access the fields of a node?

:bust_in_silhouette: Reply From: juppi

Node dosn’t have a property of type Texture:
https://docs.godotengine.org/en/stable/classes/class_node.html#properties

You can use a Sprite instead:
https://docs.godotengine.org/en/stable/classes/class_sprite2d.html

I am using “TextureRect” node, it has the property “Texture”
TextureRect — Godot Engine (stable) documentation in English

I’m trying to figure out how to access this property from a script

slavi | 2023-03-25 14:14

Yes, I thought about it, but I ran into another problem.
My script is used on different nodes, respectively, they have different names.

I tried like this

TextureRect tmpTex = GetNode((String)Name) as TextureRect;
if ((inputEvent as InputEventMouseButton).Pressed == true) tmpTex.Texture = tex2;

and like this

if ((inputEvent as InputEventMouseButton).Pressed == false) (GetNode((String)Name) as TextureRect).Texture = tex1;

It causes runtime errors:

E 0:00:23:0802 Godot.NativeInterop.NativeFuncs.generated.cs:332 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* ): Node not found: “TextureRect3” (relative to “/root/Node3D/TextureRect3”).
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> scene/main/node.cpp:1365 @ get_node()
Godot.NativeInterop.NativeFuncs.generated.cs:332 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* )
NativeCalls.cs:5886 @ Godot.GodotObject Godot.NativeCalls.godot_icall_1_658(IntPtr , IntPtr , Godot.NativeInterop.godot_node_path )
Node.cs:685 @ Godot.Node Godot.Node.GetNode(Godot.NodePath )
SlotHandler.cs:56 @ void SlotHandler.GuiInput(Godot.InputEvent )
SlotHandler_ScriptMethods.generated.cs:29 @ Boolean SlotHandler.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )

E 0:00:23:0809 SlotHandler.cs:57 @ void SlotHandler.GuiInput(Godot.InputEvent ): System.NullReferenceException: Object reference not set to an instance of an object.
<C# Error> System.NullReferenceException
<C# Source> SlotHandler.cs:57 @ void SlotHandler.GuiInput(Godot.InputEvent )
SlotHandler.cs:57 @ void SlotHandler.GuiInput(Godot.InputEvent )
SlotHandler_ScriptMethods.generated.cs:29 @ Boolean SlotHandler.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )

slavi | 2023-03-26 02:11

I checked what the GetNode() function returns.
Added two lines to the _Ready() method

var getNodeResult = GetNode(GetPath());
GD.Print(getNodeResult.GetType());

GD.Print outputs the class name of my script “SlotHandler”

But how to access the node itself (and therefore its fields) and not the script attached to it?

slavi | 2023-03-26 06:59

var slotHandler = GetNode<SlotHandler>("SlotHandler"); or
var slotHandler = (SlotHandler)GetNode("SlotHandler"); or
var slotHandler = GetNode("SlotHandler") as SlotHandler;

Moreus | 2023-03-26 10:09

:bust_in_silhouette: Reply From: Moreus

Change public partial class SlotHandler : Node to public partial class SlotHandler : TextureRect , and now you can access Texture =

Thanks for your answer, this solves the issue.

I formulated my question differently, please take a look, maybe you will have some ideas:
Access to the properties of the Node using GetNode (Godot 4, C#) - Archive - Godot Forum

slavi | 2023-03-26 11:41