C# features¶
This page provides an overview of the commonly used features of both C# and Godot and how they are used together.
Type conversion and casting¶
C# is a statically typed language. Therefore, you can't do the following:
var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);
Metoda GetNode()
zwraca instancję Węzeła
. Musisz wyraźnie przekształcić go na żądany typ pochodny, w tym przypadku Sprite
.
W tym celu w C# masz różne opcje.
Rzutowanie i sprawdzanie typu
Throws InvalidCastException
if the returned node cannot be cast to Sprite.
You would use it instead of the as
operator if you are pretty sure it won't fail.
Sprite mySprite = (Sprite)GetNode("MySprite");
mySprite.SetFrame(0);
Używanie AS jako operator
The as
operator returns null
if the node cannot be cast to Sprite,
and for that reason, it cannot be used with value types.
Sprite mySprite = GetNode("MySprite") as Sprite;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);
Using the generic methods
Generic methods are also provided to make this type conversion transparent.
GetNode<T>()
casts the node before returning it. It will throw an InvalidCastException
if the node cannot be cast to the desired type.
Sprite mySprite = GetNode<Sprite>("MySprite");
mySprite.SetFrame(0);
GetNodeOrNull<T>()
uses the as
operator and will return null
if the node cannot be cast to the desired type.
Sprite mySprite = GetNodeOrNull<Sprite>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);
**Sprawdzanie **
To check if the node can be cast to Sprite, you can use the is
operator.
The is
operator returns false if the node cannot be cast to Sprite,
otherwise it returns true.
if (GetNode("MySprite") is Sprite)
{
// Yup, it's a sprite!
}
W celu bardziej zaawansowanego sprawdzania typu, można zajrzeć do Dopasowywanie wzorów.
C# signals¶
Kompletny przykład C#, patrz Zarządzanie sygnałem w sekcji krok po kroku Scripting languages.
Deklaracja sygnału w C# odbywa się z atrybutem [Signal]
.
[Signal]
delegate void MySignal();
[Signal]
delegate void MySignalWithArguments(string foo, int bar);
These signals can then be connected either in the editor or from code with Connect
.
If you want to connect a signal in the editor, you need to (re)build the project assemblies to see the new signal. This build can be manually triggered by clicking the “Build” button at the top right corner of the editor window.
public void MyCallback()
{
GD.Print("My callback!");
}
public void MyCallbackWithArguments(string foo, int bar)
{
GD.Print("My callback with: ", foo, " and ", bar, "!");
}
public void SomeFunction()
{
instance.Connect("MySignal", this, "MyCallback");
instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");
}
Sygnały emitowane są metodą EmitSignal
.
public void SomeFunction()
{
EmitSignal(nameof(MySignal));
EmitSignal("MySignalWithArguments", "hello there", 28);
}
Zauważ, że zawsze można odwołać się do nazwy sygnału za pomocą słowa kluczowego nameof
.
It is possible to bind values when establishing a connection by passing a Godot array.
public int Value { get; private set; } = 0;
private void ModifyValue(int modifier)
{
Value += modifier;
}
public void SomeFunction()
{
var plusButton = (Button)GetNode("PlusButton");
var minusButton = (Button)GetNode("MinusButton");
plusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { 1 });
minusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { -1 });
}
Signals support parameters and bound values of all the built-in types and Classes derived from Godot.Object.
Consequently, any Node
or Reference
will be compatible automatically, but custom data objects will need to extend from Godot.Object or one of its subclasses.
public class DataObject : Godot.Object
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
Sygnały mogą być tworzone przez wywołanie AddUserSignal
, należy jednak pamiętać, że powinny być one wykonywane przed użyciem tych sygnałów (za pomocą Connect
lub EmitSignal
).
public void SomeFunction()
{
AddUserSignal("MyOtherSignal");
EmitSignal("MyOtherSignal");
}
Preprocessor defines¶
Godot has a set of defines that allow you to change your C# code depending on the environment you are compiling to.
Informacja
If you created your project before Godot 3.2, you have to modify
or regenerate your csproj file to use this feature
(compare <DefineConstants>
with a new 3.2+ project).
Przykłady¶
For example, you can change code based on the platform:
public override void _Ready()
{
#if GODOT_SERVER
// Don't try to load meshes or anything, this is a server!
LaunchServer();
#elif GODOT_32 || GODOT_MOBILE || GODOT_WEB
// Use simple objects when running on less powerful systems.
SpawnSimpleObjects();
#else
SpawnComplexObjects();
#endif
}
Or you can detect which engine your code is in, useful for making cross-engine libraries:
public void MyPlatformPrinter()
{
#if GODOT
GD.Print("This is Godot.");
#elif UNITY_5_3_OR_NEWER
print("This is Unity.");
#else
throw new InvalidWorkflowException("Only Godot and Unity are supported.");
#endif
}
Full list of defines¶
GODOT
is always defined for Godot projects.One of
GODOT_64
orGODOT_32
is defined depending on if the architecture is 64-bit or 32-bit.One of
GODOT_X11
,GODOT_WINDOWS
,GODOT_OSX
,GODOT_ANDROID
,GODOT_IOS
,GODOT_HTML5
, orGODOT_SERVER
depending on the OS. These names may change in the future. These are created from theget_name()
method of the OS singleton, but not every possible OS the method returns is an OS that Godot with Mono runs on.
When exporting, the following may also be defined depending on the export features:
One of
GODOT_PC
,GODOT_MOBILE
, orGODOT_WEB
depending on the platform type.One of
GODOT_ARM64_V8A
orGODOT_ARMEABI_V7A
on Android only depending on the architecture.One of
GODOT_ARM64
orGODOT_ARMV7
on iOS only depending on the architecture.Any of
GODOT_S3TC
,GODOT_ETC
, andGODOT_ETC2
depending on the texture compression type.Any custom features added in the export menu will be capitalized and prefixed:
foo
->GODOT_FOO
.
Jest to dobry początek dla platformówki. Bardziej dokończone demo można znaleźć w https://github.com/godotengine/godot-demo-projects/tree/master/2d/kinematic_character