Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Variante C#

Per una spiegazione dettagliata di Variant in generale, consultare la pagina di documentazione Variant.

Godot.Variant è utilizzato per rappresentare il tipo nativo di Godot Variant. Qualsiasi tipo compatibile con Variant si può convertire da/a esso. Si consiglia di evitare Godot.Variant a meno che non sia necessario interagire con API non tipizzata del motore. È meglio sfruttare la sicurezza di tipo in C# quando possibile.

È possibile convertire da un tipo C# compatibile con Variant a Godot.Variant implicitamente. Esistono anche overload del metodo CreateFrom e i metodi generici Variant.From<T>. Solo la sintassi è diversa: il comportamento è lo stesso.

int x = 42;
Variant numberVariant = x;
Variant helloVariant = "Hello, World!";

Variant numberVariant2 = Variant.CreateFrom(x);
Variant numberVariant3 = Variant.From(x);

Le conversioni implicite in Godot.Variant rendono molto comodo il passaggio di varianti come argomenti per i metodi. Ad esempio, il terzo argomento di tween_property che specifica il colore finale del tween è un Godot.Variant.

Tween tween = CreateTween();
tween.TweenProperty(GetNode("Sprite"), "modulate", Colors.Red, 1.0f);

È possibile convertire da Godot.Variant a un tipo di C# esplicitamente. Esistono anche i metodi Variant.As{TYPE} e il metodo generico Variant.As<T>. Tutti si comportano allo stesso modo.

int number = (int)numberVariant;
string hello = (string)helloVariant;

int number2 = numberVariant.As<int>();
int number3 = numberVariant.AsInt32();

Nota

I metodi Variant.As{TYPE} in genere derivano il nome dai tipi di C# (Int32), non dalle parole chiave di C# (int).

Se il tipo Variant non corrisponde al tipo di destinazione della conversione, le conseguenze variano a seconda dei valori di origine e di destinazione.

  • La conversione potrebbe esaminare il valore e restituire un valore simile ma potenzialmente inaspettato del tipo di destinazione. Ad esempio, la stringa "42a" potrebbe essere convertita nell'intero 42.

  • Potrebbe essere restituito il valore predefinito del tipo di destinazione.

  • Potrebbe essere restituito un array vuoto.

  • Potrebbe essere generata un'eccezione.

La conversione al tipo corretto evita comportamenti complicati e si dovrebbe preferire.

La proprietà Variant.Obj restituisce un object C# con il valore corretto per qualsiasi variante. Ciò potrebbe essere utile quando il tipo di Variant è completamente sconosciuto. Tuttavia, quando possibile, è preferibile effettuare conversioni più specifiche. Variant.Obj valuta uno switch su Variant.VariantType e potrebbe non essere necessario. Inoltre, se il risultato è un tipo di valore, viene "imballato".

Ad esempio, se non è accettabile che Variant.As<MyNode>() possa generare un'eccezione di conversione non valida, si può considerare l'utilizzo di un type pattern Variant.As<GodotObject>() is MyNode n.

Nota

Poiché il tipo Variant in C# è una struct, non può essere null. Per creare un Variant "null", utilizzare la parola chiave default o il costruttore senza parametri di Godot.Variant.

Tipi compatibili con Variant

Un tipo compatibile con Variant può essere convertito in e da Godot.Variant. I seguenti tipi C# sono compatibili con Variant:

Elenco completo dei tipi Variant e del loro tipo equivalente di C#:

Variant.Type

Tipo di C#

Nil

null (Non un tipo)

Bool

bool

Int

long (Godot memorizza gli interi a 64 bit in Variant)

Float

double (Godot memorizza i float a 64 bit in Variant)

String

string

Vector2

Godot.Vector2

Vector2I

Godot.Vector2I

Rect2

Godot.Rect2

Rect2I

Godot.Rect2I

Vector3

Godot.Vector3

Vector3I

Godot.Vector3I

Transform2D

Godot.Transform2D

Vector4

Godot.Vector4

Vector4I

Godot.Vector4I

Plane

Godot.Plane

Quaternion

Godot.Quaternion

Aabb

Godot.Aabb

Basis

Godot.Basis

Transform3D

Godot.Transform3D

Projection

Godot.Projection

Color

Godot.Color

StringName

Godot.StringName

NodePath

Godot.NodePath

Rid

Godot.Rid

Object

Godot.GodotObject o qualsiasi tipo derivato.

Callable

Godot.Callable

Signal

Godot.Signal

Dictionary

Godot.Collections.Dictionary

Array

Godot.Collections.Array

PackedByteArray

byte[]

PackedInt32Array

int[]

PackedInt64Array

long[]

PackedFloat32Array

float[]

PackedFloat64Array

double[]

PackedStringArray

string[]

PackedVector2Array

Godot.Vector2[]

PackedVector3Array

Godot.Vector3[]

PackedVector4Array

Godot.Vector4[]

PackedColorArray

Godot.Color[]

Avvertimento

Godot utilizza interi e float a 64 bit in Variant. Sono supportati tipi interi e float più piccoli come int, short e float, poiché si possono inserire nel tipo più grande. Si tenga presente che, quando si effettua una conversione, utilizzare un tipo errato risulterà in una potenziale perdita di precisione.

Avvertimento

Le enumerazioni sono supportate da Godot.Variant poiché il loro tipo sottostante è un tipo intero, con cui sono tutti compatibili. Tuttavia, non esistono conversioni implicite: è necessario convertire manualmente le enumerazioni nel loro tipo intero sottostante prima di poterle da/a Godot.Variant, oppure utilizzare i metodi generici Variant.As<T> e Variant.From<T> per convertirle.

enum MyEnum { A, B, C }

Variant variant1 = (int)MyEnum.A;
MyEnum enum1 = (MyEnum)(int)variant1;

Variant variant2 = Variant.From(MyEnum.A);
MyEnum enum2 = variant2.As<MyEnum>();

Utilizzare Variant in un contesto generico

Quando si utilizzano i generici, potrebbe essere interessante limitare il tipo generico T a uno solo dei tipi compatibili con Variant. Questo si può ottenere attraverso l'attributo [MustBeVariant].

public void MethodThatOnlySupportsVariants<[MustBeVariant] T>(T onlyVariant)
{
    // Do something with the Variant-compatible value.
}

In combinazione con il tipo generico Variant.From<T>, è possibile ottenere un'istanza di Godot.Variant da un'istanza di un tipo generico T. Si può quindi utilizzare in qualsiasi API che supporta solo la struct Godot.Variant.

public void Method1<[MustBeVariant] T>(T variantCompatible)
{
    Variant variant = Variant.From(variantCompatible);
    Method2(variant);
}

public void Method2(Variant variant)
{
    // Do something with variant.
}

Per richiamare un metodo con un parametro generico annotato con l'attributo [MustBeVariant], il valore deve essere un tipo compatibile con Variant o un tipo generico T anch'esso annotato con l'attributo [MustBeVariant].

public class ObjectDerivedClass : GodotObject { }

public class NonObjectDerivedClass { }

public void Main<[MustBeVariant] T1, T2>(T1 someGeneric1, T2 someGeneric2)
{
    MyMethod(42); // Works because `int` is a Variant-compatible type.
    MyMethod(new ObjectDerivedClass()); // Works because any type that derives from `GodotObject` is a Variant-compatible type.
    MyMethod(new NonObjectDerivedClass()); // Does NOT work because the type is not Variant-compatible.
    MyMethod(someGeneric1); // Works because `T1` is annotated with the `[MustBeVariant]` attribute.
    MyMethod(someGeneric2); // Does NOT work because `T2` is NOT annotated with the `[MustBeVariant]` attribute.
}

public void MyMethod<[MustBeVariant] T>(T variant)
{
    // Do something with variant.
}