C# Variant
For a detailed explanation of Variant in general, see theVariant documentation page.
Godot.Variant
is used to represent Godot's nativeVariant type. AnyVariant-compatible type can be converted from/to it.We recommend avoidingGodot.Variant
unless it is necessary to interact with untyped engine APIs.Take advantage of C#'s type safety when possible.
Converting from a Variant-compatible C# type toGodot.Variant
can be done using implicitconversions. There are alsoCreateFrom
method overloads and the genericVariant.From<T>
methods. Only the syntax is different: the behavior is the same.
intx=42;VariantnumberVariant=x;VarianthelloVariant="Hello, World!";VariantnumberVariant2=Variant.CreateFrom(x);VariantnumberVariant3=Variant.From(x);
Implicit conversions toGodot.Variant
make passing variants as method arguments very convenient.For example, the third argument oftween_propertyspecifying the final color of the tween is aGodot.Variant
.
Tweentween=CreateTween();tween.TweenProperty(GetNode("Sprite"),"modulate",Colors.Red,1.0f);
Converting fromGodot.Variant
to a C# type can be done using explicit conversions. There arealsoVariant.As{TYPE}
methods and the genericVariant.As<T>
method. All of these behave thesame.
intnumber=(int)numberVariant;stringhello=(string)helloVariant;intnumber2=numberVariant.As<int>();intnumber3=numberVariant.AsInt32();
Note
TheVariant.As{TYPE}
methods are typically named after C# types (Int32
), not C# keywords(int
).
If the Variant type doesn't match the conversion target type, the consequences vary depending on thesource and target values.
The conversion may examine the value and return a similar but potentially unexpected value of thetarget type. For example, the string
"42a"
may be converted to the integer42
.The default value of the target type may be returned.
An empty array may be returned.
An exception may be thrown.
Converting to the correct type avoids complicated behavior and should be preferred.
TheVariant.Obj
property returns a C#object
with the correct value for any variant. Thismay be useful when the type of Variant is completely unknown. However, when possible, prefer morespecific conversions.Variant.Obj
evaluates aswitch
onVariant.VariantType
and it maynot be necessary. Also, if the result is a value type, it is boxed.
For example, if the potential forVariant.As<MyNode>()
to throw an invalid cast exception isn'tacceptable, consider using aVariant.As<GodotObject>()isMyNoden
type pattern instead.
Note
Since the Variant type in C# is a struct, it can't be null. To create a "null"Variant, use thedefault
keyword or theGodot.Variant
parameterless constructor.
Variant-compatible types
A Variant-compatible type can be converted to and from aGodot.Variant
.These C# types are Variant-compatible:
All thebuilt-in value types,except
decimal
,nint
andnuint
.string
.Classes derived fromGodotObject.
Collections types defined in the
Godot.Collections
namespace.
Full list of Variant types and their equivalent C# type:
Variant.Type | C# Type |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Warning
Godot uses 64-bit integers and floats in Variant. Smaller integer and float typessuch asint
,short
andfloat
are supported since they can fit in thebigger type. Be aware that when a conversion is performed, using the wrongtype will result in potential precision loss.
Warning
Enums are supported byGodot.Variant
since their underlying type is an integertype which are all compatible. However, implicit conversions don't exist, enums mustbe manually converted to their underlying integer type before they can converted to/fromGodot.Variant
or use the genericVariant.As<T>
andVariant.From<T>
methodsto convert them.
enumMyEnum{A,B,C}Variantvariant1=(int)MyEnum.A;MyEnumenum1=(MyEnum)(int)variant1;Variantvariant2=Variant.From(MyEnum.A);MyEnumenum2=variant2.As<MyEnum>();
Using Variant in a generic context
When using generics, you may be interested in restricting the genericT
type to beonly one of the Variant-compatible types. This can be achieved using the[MustBeVariant]
attribute.
publicvoidMethodThatOnlySupportsVariants<[MustBeVariant]T>(TonlyVariant){// Do something with the Variant-compatible value.}
Combined with the genericVariant.From<T>
allows you to obtain an instance ofGodot.Variant
from an instance of a genericT
type. Then it can be used in any API that only supports theGodot.Variant
struct.
publicvoidMethod1<[MustBeVariant]T>(TvariantCompatible){Variantvariant=Variant.From(variantCompatible);Method2(variant);}publicvoidMethod2(Variantvariant){// Do something with variant.}
In order to invoke a method with a generic parameter annotated with the[MustBeVariant]
attribute, the value must be a Variant-compatible type or a genericT
type annotatedwith the[MustBeVariant]
attribute as well.
publicclassObjectDerivedClass:GodotObject{}publicclassNonObjectDerivedClass{}publicvoidMain<[MustBeVariant]T1,T2>(T1someGeneric1,T2someGeneric2){MyMethod(42);// Works because `int` is a Variant-compatible type.MyMethod(newObjectDerivedClass());// Works because any type that derives from `GodotObject` is a Variant-compatible type.MyMethod(newNonObjectDerivedClass());// 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.}publicvoidMyMethod<[MustBeVariant]T>(Tvariant){// Do something with variant.}