Особенности C#

На этой странице представлен обзор наиболее часто используемых функций C# и Godot, а также того, как они используются вместе.

Превращение типов и кастинг

C# - это статически типизированный язык. Следовательно, вы не можете сделать следующее:

var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);

Метод GetNode() возвращает экземпляр Node. Вы должны однозначно преобразовать его в желаемый производный тип, Sprite в данном случае.

Для этого в C# имеются различные опции.

Приведение и проверка типа

Выдает `` InvalidCastException``, если возвращаемый узел не может быть приведен к Sprite. Вы можете использовать его вместо оператора `` as``, если уверены, что он не потерпит неудачу.

Sprite mySprite = (Sprite)GetNode("MySprite");
mySprite.SetFrame(0);

** Использование оператора AS **

Оператор as возвращает null, если узел не может быть приведен к Sprite, и по этой причине его нельзя использовать с типами значений.

Sprite mySprite = GetNode("MySprite") as Sprite;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

** Использование универсальных методов **

Общие методы также предоставляются, чтобы сделать это преобразование типов прозрачным.

GetNode<T>() преобразует узел перед его возвратом. Он выдаст InvalidCastException, если узел не может быть приведен к нужному типу.

Sprite mySprite = GetNode<Sprite>("MySprite");
mySprite.SetFrame(0);

GetNodeOrNull<T>() использует оператор as и вернет null, если узел не может быть приведен к нужному типу.

Sprite mySprite = GetNodeOrNull<Sprite>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

** Проверка типа с использованием оператора IS **

Чтобы проверить, может ли узел быть приведен к Sprite, вы можете использовать оператор is. Оператор is возвращает false, если узел не может быть приведен к Sprite, в противном случае он возвращает true.

if (GetNode("MySprite") is Sprite)
{
    // Yup, it's a sprite!
}

Для более сложной проверки типов вы можете посмотреть в Сопоставление шаблонов.

Сигналы C#

Для полного C# примера см. Раздел ** Обработка сигнала ** в пошаговом руководстве Написание скриптов.

Объявление сигнала в C# выполняется с помощью атрибута [Signal] делегата.

[Signal]
delegate void MySignal();

[Signal]
delegate void MySignalWithArguments(string foo, int bar);

Эти сигналы затем могут быть подключены либо в редакторе, либо из кода с помощью `` Connect``. Если вы хотите подключить сигнал в редакторе, вам нужно собрать проект, чтобы увидеть новый сигнал. Эту сборку можно запустить вручную, нажав кнопку «Построить» в верхнем правом углу окна редактора.

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");
}

Излучение сигналов осуществляется методом EmitSignal.

public void SomeFunction()
{
    EmitSignal(nameof(MySignal));
    EmitSignal("MySignalWithArguments", "hello there", 28);
}

Обратите внимание, что вы всегда можете сослаться на имя сигнала используя ключевое слово nameof (применяется к самому делегату).

Возможно связывать значения при установке соединения передавая массив Godot.

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 });
}

Сигналы поддерживают параметры и связанные значения всех встроенных типов и Классов, полученных из Godot.Object. Следовательно, любой Node или Reference будут совместимы автоматически, но пользовательские объекты данных должны наследоваться из Godot.Object или одного из его подклассов.

public class DataObject : Godot.Object
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}

Наконец, сигналы могут быть созданы путем вызова `` AddUserSignal``, но имейте в виду, что он должен выполниться перед любым использованием указанных сигналов (с помощью `` Connect`` или `` EmitSignal``).

public void SomeFunction()
{
    AddUserSignal("MyOtherSignal");
    EmitSignal("MyOtherSignal");
}

Препроцессорные определения

Godot имеет набор определений, которые позволяют изменять код C# в зависимости от среды, в которую вы компилируете.

Примечание

Если вы создали свой проект до Godot 3.2, вам придется изменить или регенерировать свой файл csproj, чтобы использовать эту функцию (сравните <DefineConstants> с новым проектом 3.2+).

Примеры

Например, вы можете изменять код в зависимости от платформы:

    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
    }

Или вы можете определить, в каком движке будет находиться ваш код, что полезно для создания кросс-движковых библиотек:

    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
    }

Полный список определений

  • GODOT всегда объявлен в проектах Godot.

  • Один из GODOT_64 или GODOT_32 определяется в зависимости от того, если архитектура будет 64-bit или 32-bit соответственно.

  • One of GODOT_X11, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, GODOT_IOS, GODOT_HTML5, or GODOT_SERVER depending on the OS. These names may change in the future. These are created from the get_name() method of the OS singleton, but not every possible OS the method returns is an OS that Godot with Mono runs on.

При экспорте также могут быть определены следующие параметры в зависимости от особенностей экспорта:

  • Один из GODOT_PC, GODOT_MOBILE, или GODOT_WEB в зависимости от типа платформы.

  • Один из GODOT_ARM64_V8A или GODOT_ARMEABI_V7A на Android только в зависимости от архитектуры.

  • Один из GODOT_ARM64 или GODOT_ARMV7 на iOS только в зависимости от архитектуры.

  • Любой из GODOT_S3TC, GODOT_ETC, и GODOT_ETC2 в зависимости от типа сжатия текстур.

  • Любые пользовательские функции, добавленные в меню экспорта, будут написаны заглавными буквами и с префиксом: foo -> GODOT_FOO.

Чтобы увидеть пример проекта, см. демонстрационную версию тестирования ОС: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test