intuitive-arts Initialize it in the constructor.
how to use an instance of custom class in GDScript?
xyz
it doesn't change, and the problem is with the string field "imagen". By some reason Godot doesn't recognize the existence of my object monstruito which is an instance of Monstruo, or its field "imagen".
Thanks for your help. Do you know why it may be happening?
When I put the value of monstuito.imagen to a variable in the same globals file, it can see it perfectly. But not directly in the instance of the object.
intuitive-arts it doesn't change
It doesn't change if you declare it non static and initialize it in the constructor?
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.
intuitive-arts Let's see the whole code. Please format it properly using ~~~
Or better yet post the minimal project that reproduces the problem.
xyz thanks I'll do it tomorrow as I am not in the pc.
- Edited
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;
}
- Edited
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()
{
}
- Edited
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.
intuitive-arts No, it must work. You probably overlooked something. Can you post a minimal project with your implementation of the example?
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.
- Edited
- Best Answerset by intuitive-arts
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)
- Edited
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 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:
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.
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.