Особливості 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. Якщо ви хочете підключити сигнал в редакторі, вам потрібно (пере)скласти збірку проєктів, щоб побачити новий сигнал. Цю збірку можна вручну запустити, натиснувши кнопку «Створити» (“Build”) у верхньому правому куті вікна редактора.

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

Preprocessor визначення

У 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-бітна, чи 32-бітна.

  • 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