• Godot Help
  • how to use an instance of custom class in GDScript?

xyz no it doesn't.
I am adapting a game i made in C#.
in Visual studio it worked, but i have this problem here.

  • xyz replied to this.

    intuitive-arts Let's see the whole code. Please format it properly using ~~~
    Or better yet post the minimal project that reproduces the problem.

      intuitive-arts Don't forget that your custom class needs to inherit at least from RefCounted (or Reference in 3.x) in order for GDScript to "see" the object.

      public partial class Monster: RefCounted {
      	int eyesCount = 3;
      }

        xyz it seems to stop complaining the same errors, but now it says:
        Invalid get index 'monstruito' (on base: 'Nil').

        It is in this function:
        func _on_Button_pressed():
        $TextureRect.texture = ResourceLoader.load("res://" + Globals.monstruito.imagen)
        pass # Replace with function body.

        And the Monstruo class is this way:

        using System;
        
        	[Serializable]
        	public partial class Monstruo: Reference
        	{
        		public int life;
        		public int maxLife; // vida inicial
        		public int attack;
        		public int defense;
        		public int dexterity;
        		public string name;
        		public string imagen;//Imagen de (Image)Resources.
        		public int level;
        
        		public string descripcion;
        		public string[] ataques;
        
        		public enum tipo
        		{
        			BESTIA = 1,
        			REPTIL = 2,
        			FUEGO = 3,
        			AGUA = 4,
        			PARANORMAL = 5,
        			PERRO = 6,
        			NOMUERTO = 7,
        			DEMONIO = 8,
        			DRAGON = 9
        		};
        		public tipo especie; // tipo de monstruo para sonido de encuentro
        
        		// nota un monstruo puede ser vulnerable solo a un tipo de magia
        		public enum magia
        		{
        			TODO = 1, // le daña todo
        			NADA = 2, // no le daña ninguna magia
        			FUEGO = 3, // solo le daña el fuego
        			AGUA = 4, // solo el agua
        			AIRE = 5, // solo el aire
        			TIERRA = 6, // solo la tierra
        			ESPACIO = 7 // solo vulnerable a magia espaciotemporal
        		};
        		public magia debilidad;
        		///////////////////////////////////////////////////////////////////////////////////////////////////
        		// rutina RUTINAS * RUTINAS * RUTINAS * RUTINAS * RUTINAS * RUTINAS * RUTINAS * RUTINAS * RUTINAS 
        		///////////////////////////////////////////////////////////////////////////////////////////////////
        		public Monstruo
        			(
        			int life,
        			int maxLife,
        			int attack,
        			int defense,
        			int dexterity,
        			string name,
        			string imagen ="",
        			int level=1,
        
        			string descripcion="",
        			string[] ataques = null,
        		
        			tipo especie = tipo.BESTIA, // el monstruo por defecto es una bestia
        			magia debilidad = magia.TODO // y es vulnerable a todo tipo de magia
        			)
        
        		{
        			this.life = life;
        			this.maxLife = maxLife;
        			this.attack = attack;
        			this.defense = defense;
        			this.dexterity = dexterity;
        			this.name = name;
        			this.imagen = imagen;
        			this.level = level;
        
        			this.descripcion = descripcion;
        			this.ataques = ataques;
        
        			this.especie = especie;
        			this.debilidad = debilidad;
        		}
        
        		///////////////////////////////////////////////// END OF PRINT //////////////////////////// END OF PRINT /////////////////////// END OF PRINT /////////////////////////
        	} // fin clase

        And the Globals.cs is this:

        using Godot;
        using System;
        
        public partial class Globals : Node
        {
        	// Declare member variables here. Examples:
        	// private int a = 2;
        	// private string b = "text";
        	
        	
        	public static Monstruo monstruito = new Monstruo(10, 10, 30, 20, 10, "Golem", "art/monsters/E_golem.jpeg", 2,
        	"A golem is a cursed giant made of mud or stone, that follows the commands of a wizard to kill intruders.",
        	new String[2] {"using his fists to crunch her", "trying to smash her with his brute force" },
        	Monstruo.tipo.BESTIA, Monstruo.magia.AGUA) ;
        
        	string ruta = monstruito.imagen; // coloca este atributo en una variable para poderlo invocar desde gdscript
        	// porque no se como hacerlo directamente, o bien es que gdscript se lia
        	
        	// Called when the node enters the scene tree for the first time.
        	public override void _Ready()
        	{
        		
        	}
        • xyz replied to this.

          intuitive-arts Yeah but you still have monstruito declared as a static member.
          This should work:
          Monster.cs:

          using Godot;
          
          public partial class Monster: RefCounted {
          	int eyesCount = 3;
          }

          Globals.cs:

          using Godot;
          
          public partial class Globals: Node
          {
          	Monster m = new Monster();
          }

          something.gd:

          extends Node
          
          func _ready():
          	print(globals.m.eyesCount)

          The singleton/autoload is set under name globals.

            xyz I made the example you posted, and it happens the same:
            Invalid get index 'm' (on base: 'Nil').

            In the Errors list it also says:
            E 0:00:01:0164 start: Script does not inherit from Node: res://Globals.cs.
            <C++ Error> Condition "!valid_type" is true. Continuing.
            <C++ Source> main/main.cpp:2776 @ start()

            Maybe I should use GDScript only?

              intuitive-arts It works with GD Script with simple variables, but it doesn't seem to work with C# on custom classes. The m monster doesn't seem to be recognized. A simple string variable is, if I create a GD script that defines it.

              • xyz replied to this.

                intuitive-arts No, it must work. You probably overlooked something. Can you post a minimal project with your implementation of the example?

                  xyz

                  caverns-and-dryads.zip
                  7MB

                  Thank you so much for your help. This is a minimal test. If the script in Globals is GDScript it works, but not for C#. There's a line that you can uncomment in "something.gd" so you can test the C# part.

                  • xyz replied to this.

                    intuitive-arts
                    Firstly, Monster m; should be declared inside the Globals class not outside of it. So again:

                    using Godot;
                    
                    public partial class Globals: Node
                    {
                    	Monster m = new Monster();
                    }

                    Other than that, script sources are fine.

                    There were apparently some known issues with this.

                    If I make a new autoload class in your project it works just fine, but yours causes a complaint that the class does not inherit from Node, even though it does.

                    Try this:

                    • delete *.vcproj file in your project folder
                    • open the project
                    • remove the cs script from autoloads.
                    • go to Project->Tools->C#->Create C# solution
                    • add the cs script as autoload
                    • try to run the project

                    Also make sure that the class name and *.cs file name are exactly the same (the case must match too)

                      xyz

                      The instance "m" of Monster is declared inside Globals here:

                      `using Godot;

                      Monster m;

                      public partial class Globals: Node
                      {
                      m = new Monster();
                      }
                      `

                      Do you mean that I should put the declaration of the class Monster inside Globals, instead that in another file (Monster.cs)?

                      • xyz replied to this.

                        xyz can you upload the version that works for you, that uses the C# class, so I can have a look? Thank you so much!

                        intuitive-arts Do you mean that I should put the declaration of the class Monster inside Globals, instead that in another file (Monster.cs)?

                        I meant to put the declaration of the variable m inside class body.

                        Here's the project:

                        caverns-and-dryads.zip
                        363kB

                          xyz Thank you, I will try that way and cleaning the files you told me. Thanks a lot for your time and for helping me with this.

                          xyz OK. I did the following for getting it to work with my full class:

                          • As you said, the declaration was outside. It has to be inside
                          • I deleted the file with csproj extension and the old solution if existed
                          • I used the menu for creating the solution again
                          • And after that, it didn't work, and it seems it was because I had a typo in the name of my variable. The program told me it doesn't existed, because it didn't!
                          • After that, I tried my original code to change the TextureRect texture with a button, and it didn't work neither. I have no idea why, but I just deleted it, added a TextureRect again, and now everything works.

                          As now I know that my custom C# code works, I will be able to make my game. Thanks a lot, you are fantastic!
                          For me it was confusing that the editor didn't warn me that the variable name was spelled wrong. Usually that gives a red line in Visual Studio below the word so you know in the moment that it wasn't. I suppose that in some place or using Visual Studio or Visual Studio Code as editors it may warn me, right?
                          The other thing is that I don't knwo why the TextureRect stopped working, or maybe it was not visible by some reason.

                          • xyz replied to this.

                            intuitive-arts Something was definitely bugged out in your project. Not sure exactly what. But this in principle must work.
                            As for error highlighting, GDScript cannot check C# source files for errors while you're typing (i.e. prior to runtime). It can only do so for its own code. C# is not as well integrated into Godot as GDScript.