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

Что ж, у меня есть руководство для вас, но это приключение не для слабонервных. Вы столкнетесь с множеством проблем с интеграцией с Godot, а также с проблемами с Rust.

С другой стороны, вы будете писать надежный и производительный игровой код. Код, который можно использовать на нескольких платформах (Windows, Mac и Linux ... даже WebAssembly). Кроме того, используя Godot, вы получаете отличный 2D- и 3D-движок, который вы можете перестроить в соответствии с вашими потребностями из исходного кода по очень разрешительной лицензии MIT.

В этом уроке я покажу вам, как начать. Вместе мы загрузим Godot, настроим привязки GDNative, и я покажу вам, как заставить пример работать. Я покажу вам пример кода. На основании ваших вопросов я создам больше руководств, чтобы охватить сложные моменты.

Если вы хотите узнать больше о том, как я использую Godot и Rust в The Recall Singularity, перейдите к моей предыдущей статье. Или прочтите Повесть о завоеваниях, чтобы узнать, что я делаю.

Вот краткое описание того, что мы собираемся сделать:

  1. Убедитесь, что вы используете 64-битную версию Godot (или измените последующие шаги).
  2. Получите привязки GDNative (клонируйте их локально)
  3. Загляните в примеры \ hello_world (файлы объясняются в руководстве)
  4. Убедитесь, что Clang установлен на вашем пути, и что ржавчина использует 64-битную цель
  5. Сборка груза в папке с примерами
  6. Убедитесь, что цель Godot совпадает с выходным местоположением
  7. Запускаем Godot, импортируем пример проекта.
  8. Запускаем проект, наблюдаем «Hello world»

Давайте установим Годо

Установить Godot так же просто, как зайти на https://godotengine.org/ и нажать Загрузить. Выберите стандартную 64-битную версию, хотя я не буду судить, нужна ли вам и поддержка Mono. Я использую эту конкретную версию:

Https://downloads.tuxfamily.org/godotengine/3.1.1/Godot_v3.1.1-stable_win64.exe.zip

Вы обнаружите, что есть единственный двоичный файл, который вы только что скачали. Моя версия называется Godot_v3.1.1-stable_win64.exe - Поздравляю, вы только что «установили» Godot. Нам пока не нужно запускать это.

Установите Rust

Если у вас не установлен ржавчина, вы должны следовать инструкциям здесь. В окнах текущие инструкции говорят скачать и запустить« rustup-init.exe ».

Если у вас уже был установлен rust, я предлагаю вам использовать «rustup update», чтобы убедиться, что все в вашей установке обновлено.

›обновление rustup

Получите GDNative - Rust Bindings

Теперь нам нужно получить привязки, которые мы собираемся использовать для связи между Godot и Rust. Проверять этот код из Git не обязательно, но мне нравится это делать, потому что сейчас мы собираемся использовать примеры из репозитория.

Мы собираемся создать ящик Rust, у которого есть «цель» - динамически связанная библиотека (DLL). Когда Godot запущен, наш игровой проект скажет ему загрузить эту DLL. Привязки Godot - Rust помогут нам сообщить Godot, что может делать наша DLL (какие классы / «скрипты» находятся внутри нее), и помогут нам звонить Godot, чтобы сообщить ИТ, что делать с нашей игрой.

Хорошо, давай возьмем эти привязки. Вы можете найти их онлайн на GitHub, давайте их клонируем. Если у вас еще не установлен Git, возможно, вы захотите сделать это сейчас. Я также использую Git Extensions, который является действительно хорошим бесплатным графическим интерфейсом для git.

Я проверил фиксацию 491904858462875a, которая представляет собой «Запрос на объединение № 203»

Выберите любой:

›git clone https://github.com/GodotNativeTools/godot-rust.git

Или, возможно, вы предпочитаете использовать Git Extensions, которые дают нам хороший щелчок правой кнопкой мыши для клонирования меню

Давайте посмотрим, что у нас получилось

После получения перейдите в репозиторий. Вы найдете папку examples / hello_world

›Cd C: \ code \ godot-rust \ godot-rust \ examples \ hello_world

Cargo.toml - сообщает ржавчине, что это компилируемый ящик. Определяет, какие зависимости имеет наш ящик, включая gdnative

hello_world_library.gdnlib - сообщает Godot, где найти скомпилированный вывод из Rust (или другого языка, например C ++). Инструкции для этого здесь.

Main.tscn - Сцена с Годо. Определяет, где находятся разные объекты для просмотра Годо. Вы будете много редактировать такие сцены в «Годо».

project.godot - сообщает Годо, что это папка, которую вы можете загрузить.

Давайте построим и запустим пример.

Хорошо, мы переходим в каталог примеров и строим пример. Посмотрим, работает ли это….

На моем компьютере это не удалось, потому что я выбрал неправильную цель сборки для Godot (я использовал GNU), но, вероятно, вы столкнетесь с этой проблемой, потому что вы не установили Lib Clang. Если вам нужно установить Lib Clang, сделайте это.

Если у вас возникнут проблемы с этим или другим вопросом, дайте мне знать. Прошло много времени с тех пор, как все это работало, и, возможно, я забыл шаг здесь.

Давайте сначала проверим нашу цель сборки на наличие ржавчины (я поставил здесь стабильную версию, но вы можете использовать каждую ночь - для потрясающих функций, я знаю, что обычно делаю):

›Rustup default stable-x86_64-pc-windows-msvc

Примечание. Поскольку мы используем 64-битный Godot, описанный выше, нам понадобится целевой объект x86_64, иначе когда вы загрузите DLL, Godot будет ПРОСТО КРАШИТЬ. Если вы пытаетесь написать 32-битную игру, используйте -i686-, а не -x86_64-.

Куда пропал мой результат?

Оказывается, проект examples / hello_world / не является автономным в более крупном репозитории godot-rust.

В Rust есть концепция под названием Рабочие области. Репозиторий godot-rust git имеет один настроенный в корневой папке, см. C: \ code \ godot-rust \ godot-rust \ Cargo.toml, и вы поймете, что наш пример не является самостоятельным. .

Из-за рабочей области любой результат компиляции чего-либо (например, в этом примере) попадает в каталог root / target. Вы найдете свой ценный пример вывода на сайте

C: \ code \ godot-rust \ godot-rust \ target \ debug \ hello_world.dll

Используете Linux? Ожидайте libhello_world.so. Mac? libhello_world.dylib

Чтобы найти эту DLL, Годоту нужна эта строка в hello_world_library.gdnlib

[Строка 5] Windows.64 = "res: //../../target/debug/hello_world.dll"

(Мне пришлось добавить это, я поставлю PR, чтобы исправить это в godot-rust)

Давайте загрузим Годо

Ладно, подпрыгиваем на пару папок и запускаем Годо. После заставки вы должны увидеть менеджера проекта. Я хочу, чтобы вы нажали здесь кнопку импорта.

Скажите Годо, чтобы он импортировал проект в нашу папку примеров. Он заметит файл проекта и добавит его в список.

C: \ code \ godot-rust \ godot-rust \ examples \ hello_world

Двойной щелчок по этому новому проекту в списке приведет вас в Godot.

Я хотел бы обратить ваше внимание на небольшой свиток вверху слева. В этом примере узел имеет скрипт, предоставляемый Rust. Если вы новичок в Godot, вам нужно следовать руководству« Ваша первая игра », прежде чем пытаться делать здесь много редактирования.

После того, как вы какое-то время используете Godot, вы узнаете, что скрипты обычно являются GDScript, но в данном случае это GDNative.

Давайте рассмотрим настройку GDNative

  1. При нажатии на узел открываются параметры сценария.
  2. Затем щелкните темно-синюю область, чтобы отобразить информацию GDNative.

Обратите внимание, что у нас есть имя класса «HelloWorld».

Мы также ссылаемся на hello_world_library.gdnlib, который мы создали ранее.

Запустим нашу «Игру»

Нажмите F5 или нажмите кнопку Play, и вы получите очень не впечатляющий проект. Но он передает привет, мир!

Вы видите это как в текстовой консоли, так и в Godot Gui?

Давайте посмотрим на исходный код

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

#[macro_use]
extern crate gdnative;

Первый импорт gdnative. Если вы посмотрите на cargo.toml, то заметите, что он определен как находящийся в соседней папке. Позже я покажу вам, как перейти от примера к полноценному проекту.

#[derive(gdnative::NativeClass)]
#[inherit(gdnative::Node)]
#[user_data(gdnative::user_data::ArcData<HelloWorld>)]
struct HelloWorld;

struct HelloWorld; - это объявление в Rust структуры, которая вообще не хранит данных. Над ним 3 декоратора

  1. # [derive (gdnative :: NativeClass)] - Добавляет процедуры, необходимые Годо для связи с этим классом.
  2. # [inherit (gdnative :: Node)] - Сообщите Godot, от какого класса вы создаете подкласс. Я считаю, что это также позволяет вам вызывать процедуры базового класса.
  3. … На самом деле я не знаю, что делает # [user_data (gdnative :: user_data :: ArcData ‹HelloWorld›)].
#[gdnative::methods]
impl HelloWorld {
    fn _init(_owner: gdnative::Node) -> Self {
        HelloWorld
    }

    #[export]
    fn _ready(&self, _owner: gdnative::Node) {
        godot_print!("hello, world.")
    }
}

Для каждого объекта, который вы пишете на Rust и который вызывается godot, требуется метод _init, который создает и возвращает экземпляр структуры. Здесь это не так уж много.

Единственная функция, которую мы экспортируем в Godot, - это функция _ready - специальная функция, которая вызывается Godot после добавления узла в сцену (или запуска игры в этом случае)… и вы увидите инструкцию для печати.

fn init(handle: gdnative::init::InitHandle) {
    handle.add_class::<HelloWorld>();
}

godot_gdnative_init!();
godot_nativescript_init!(init);
godot_gdnative_terminate!();

Когда Godot загружает нашу библиотеку, ему нужно найти 3 различных функции точки входа. Бинды Godot-rust позаботятся об этом с помощью 3 макросов. Вам нужно определить функцию init, и вам нужно будет добавить здесь строку, которая регистрирует каждый класс, который вы добавляете по мере роста вашего проекта. Прочтите документацию или источник, чтобы узнать больше о том, как они работают.

Что дальше - решать вам!

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

В качестве подсказки попробуйте переместить этот пример (или, возможно, пример scene_create) в отдельную папку. Затем измените

gdnative = { path = "../../gdnative" }

В :

gdnative = { path = "C:\code\godot-rust\godot-rust\gdnative" }

Документация по API

Чтобы сделать что-нибудь действительно полезное в Rust, вам нужно будет вызвать функции внутри Godot. Некоторые из API являются потокобезопасными, некоторые - нет. Все безопасно вызывать, если вы находитесь «внутри» функции, вызываемой из Godot.

Существует документация по API для различных частей godot-rust online, с которой вы можете ознакомиться, чтобы узнать, что вы можете сделать.

Например, вы найдете документацию для синглтона« Input здесь» и увидите, что вам нужно вызвать Input.godot_singleton (), который возвращает экземпляр, который затем можно использовать для дальнейшего вызова Input. функции на.

Так что назвать это было бы что-то вроде

let UI_up = GodotString::from_str("UI_up");
if Input::godot_singleton().is_action_pressed(UI_up) {
   // Your code here
}

Пока я обрабатываю весь ввод в GDScript, а затем вызываю Rust для выполнения тяжелой работы. Большинство вызовов API, которые я сейчас выполняю, перемещают узлы в дереве Godot Scene из Rust.

Пожалуйста прочти

Если вы хотите вдохновиться моей структурой кода, я объяснил это в разделе Базовая структура Godot & Rust. Или вы можете узнать больше о как я использую 3D-ресурсы.

Соучастник читателя Ардаван Изади предоставил полезный сценарий оболочки Godot Setup (для mac / linux), который (при запуске в пустой папке) должен настроить все за вас. Перед запуском сделайте резервную копию своей работы.

Не стесняйтесь подписываться на меня в твиттере, если вы хотите прочитать другие подобные руководства и прочитать много обновлений о моей предстоящей игре, использующей Godot и Rust для создания космических фабрик. Или не стесняйтесь приходить и тусоваться на сервере Discord.