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.

Основные функции и типы

API godot-cpp разработан так, чтобы быть максимально похожим на внутренний API Godot.

Это означает, что в общем случае вы можете использовать раздел Сведения о движке для изучения работы с godot-cpp. Кроме того, часто бывает полезно просмотреть код движка для поиска примеров работы с API Godot.

Тем не менее, есть некоторые различия, о которых следует знать, и они описаны здесь.

Общие функции и макросы

Пожалуйста, обратитесь к Общие методы и макросы движка для получения информации об этом. Функции и макросы, описанные там, также доступны в godot-cpp.

Основные типы

Основные типы Godot также доступны в godot-cpp, и применяются те же рекомендации, что описаны в этой статье. Типы регулярно синхронизируются с кодовой базой Godot.

В вашем собственном коде вы также можете использовать типы C++ STL или типы из любой библиотеки по вашему выбору, но они не будут совместимы с API Godot.

Упакованные массивы

В Godot типы Packed*Array являются псевдонимами Vector, а в godot-cpp они являются собственными типами, использующими привязки Godot. Это связано с тем, что Packed*Array доступны в Godot и ограничены только типами Godot, тогда как Vector может содержать любой тип C++, который Godot может не понимать.

В целом типы Packed*Array работают так же, как их псевдонимы Vector, однако есть некоторые заметные различия.

Доступ к данным

Vector хранит свои данные полностью в GDExtension, тогда как типы Packed*Array хранят свои данные на стороне Godot. Это означает, что при каждом обращении к Packed*Array требуется вызов Godot.

Для эффективного чтения или записи большого объёма данных в Packed*Array следует вызывать .ptr() (для чтения) или .ptrw() (для записи), чтобы получить указатель непосредственно на память массива:

// BAD!
void my_bad_function(const PackedByteArray &p_array) {
    for (int i = 0; i < p_array.size(); i++) {
        // Each time this runs it needs to call into Godot.
        uint8_t byte = p_array[i];

        // .. do something with the byte.
    }
}

// GOOD :-)
void my_good_function(const PackedByteArray &p_array) {
    const uint8_t *array_ptr = p_array.ptr();
    for (int i = 0; i < p_array.size(); i++) {
        // This directly accesses the memory!
        uint8_t byte = array_ptr[i];

        // .. do something with the byte.
    }
}

Копирование

Обёртки Variant для Packed*Array рассматривают их как передаваемые по ссылке, тогда как сами типы Packed*Array передаются по значению (реализованы как копирование при записи).

Кроме того, может быть интересно, что вызовы GDScript используют интерфейс вызовов Variant: любые аргументы Packed*Array ваших функций будут переданы в Variant и распакованы оттуда. Это может создавать копии типов, поэтому полученный вами аргумент может быть копией аргумента, с которым была вызвана функция. На практике это означает, что вы не можете полагаться на то, что переданный вам аргумент может быть изменён на стороне вызывающего.

Класс Variant

Обратитесь к Класс Variant, чтобы узнать, как работать с Variant.

Самое важное, вы должны знать, что все функции, предоставляемые через API GDExtension, должны быть совместимы с Variant.

Класс Object

Обратитесь к Класс Object, чтобы узнать, как регистрировать и работать с собственными типами Object.

Нам не известно о каких-либо серьёзных различиях между API Object godot-cpp и внутренним API Object Godot, за исключением того, что некоторые методы доступны во внутреннем API Godot, но недоступны в godot-cpp.

Вы должны знать, что указатель на ваш Object godot-cpp отличается от указателя, который Godot использует внутри. Это связано с тем, что версия godot-cpp является экземпляром расширения, выделенным отдельно от исходного Object. Однако на практике это различие обычно незаметно.