reckfellENGINE

Скрипты C#

Первый скрипт, сборка, жизненный цикл, пути и проверка ссылок после удаления.

На этой странице

Нужен Cube типа MeshInstance3D из создания проекта.

1. Создайте и прикрепите скрипт

  1. Остановите игру через F8 и выберите Cube типа MeshInstance3D в локальной иерархии.
  2. Нажмите кнопку прикрепления скрипта. Выберите C#, базовый класс Entity3D и путь asset://Scripts/Rotator.cs. Создайте папку Scripts, если её ещё нет.
  3. Если редактор предлагает создать решение C#, подтвердите. Оно нужно для сборки кода проекта.
  4. Откройте Rotator.cs в редакторе кода. Полностью замените содержимое примером ниже и сохраните файл.

Имя файла и имя класса должны совпадать: Rotator.cs и Rotator. Скрипт должен быть прикреплён к кубу, а не просто лежать в Assets. MeshInstance3D наследует Entity3D, поэтому выбранный базовый класс подходит.

Если файл не открывается автоматически, найдите Scripts/Rotator.cs в папке проекта и откройте установленным текстовым редактором. Для первого примера достаточно редактора, который сохраняет обычный текст с расширением .cs, без добавления .txt. Сборку всё равно выполняет Reckfell.

2. Полный скрипт

C#
using Reckfell;

public partial class Rotator : Entity3D
{
    [Export] public float DegreesPerSecond { get; set; } = 45.0f;

    public override void _Ready()
    {
        ReckfellApi.Print("Rotator ready");
    }

    public override void _Process(double delta)
    {
        float angle = Mathf.DegToRad(DegreesPerSecond) * (float)delta;
        RotateY(angle);
    }
}

3. Соберите и запустите

В редакторе выберите Build Project / Собрать проект в инструментах C#; стандартная комбинация — Alt + B. Дождитесь завершения без ошибок. Сохраните документ и нажмите F6.

Ожидаемый результат: куб вращается вокруг вертикальной оси, а в Output появляется Rotator ready. Если он остаётся неподвижным, проверьте, что последняя сборка завершилась успешно и скрипт прикреплён именно к видимому кубу.

Как читать этот код

ЗаписьПростое объяснение
using Reckfell;Позволяет использовать типы движка без полного имени перед каждым типом
class Rotator : Entity3DОписывает поведение объекта на основе Entity3D
partialПозволяет генератору движка дополнить класс необходимой служебной частью
floatЧисло с дробной частью; суффикс f в 45.0f задаёт этот тип
[Export]Делает свойство доступным в инспекторе после сборки
_Ready()Выполняется при готовности объекта и его детей
_Process(double delta)Выполняется каждый отображаемый кадр
RotateY(angle)Поворачивает объект вокруг оси Y на угол в радианах

Фигурные скобки { } объединяют инструкции. Точка с запятой ; завершает отдельную инструкцию. public позволяет обращаться к члену класса извне, void означает, что метод не возвращает значение, а override заменяет обработчик, предусмотренный базовым классом.

Зачем нужна delta

DegreesPerSecond задаёт скорость за секунду, а delta — сколько секунд прошло с предыдущего кадра. Их произведение даёт изменение за один кадр. При скорости 45 за две секунды объект повернётся примерно на 90 градусов независимо от обычных колебаний частоты кадров.

Инспектор показывает градусы, но RotateY() принимает радианы. Mathf.DegToRad() переводит одно в другое. Если убрать умножение на delta, получится поворот на заданный угол каждый кадр: скорость станет зависеть от FPS.

Измените скорость без правки кода

Остановите игру, выберите куб и найдите свойство Degrees Per Second в инспекторе скрипта. Поставьте 90, сохраните и запустите: вращение станет вдвое быстрее. Значение -45 меняет направление, 0 останавливает вращение.

Значение в инспекторе сохраняется отдельно от начального значения в C#. Если оно уже переопределено, изменение 45.0f в тексте скрипта может не заменить значение, сохранённое у объекта.

Когда выполняется код

МетодКогда нужен
_EnterTree()При каждом добавлении в работающую иерархию; подключайте подписки, действующие только внутри уровня
_Ready()Когда готовы дочерние объекты; получайте ссылки и задавайте начальное состояние
_Process(double delta)Каждый отображаемый кадр; анимация интерфейса и визуальные изменения
_PhysicsProcess(double delta)На физическом шаге; движение физического тела и работа со столкновениями
_ExitTree()При выходе из иерархии; отключайте подписки на объекты, которые продолжают жить

Родитель входит в дерево раньше детей, а _Ready() детей выполняется раньше _Ready() родителя. Поэтому в _Ready() удобно связывать уже подготовленные дочерние компоненты. Конструктор C# не означает, что объект уже находится в уровне: не получайте там GetTree() или игровые дочерние объекты.

_Ready() обычно вызывается один раз за жизнь экземпляра. Если тот же объект убрать через RemoveChild() и вернуть через AddChild(), снова выполнятся _EnterTree() и _ExitTree(), но не _Ready(). Если повторная подготовка действительно нужна, вызовите RequestReady() до следующего добавления. Запрос относится к этому объекту, а не ко всем его детям.

Для персонажа используйте _PhysicsProcess() из урока движения. Не переносите туда любой код только ради стабильной частоты: вращение декоративного куба не требует физического шага.

Ссылки на объекты и пути

GetEntity<T>("Child") ищет объект относительно того, на котором выполняется скрипт. Имя и регистр должны совпадать с иерархией. Это не путь к файлу: asset://Props/Crate.rprefab загружается через ResourceLoader, а экземпляр создаётся отдельно. См. создание объектов.

Когда отсутствие дочернего объекта допустимо, используйте GetEntityOrNull<T>() и проверяйте результат. Когда объект обязателен, исправьте структуру уровня: молчаливый пропуск ошибки оставит компонент неработающим.

После QueueFree() native-объект удаляется в конце кадра. C#-переменная сама не становится null. Для сохранённой ссылки проверяйте ReckfellObject.IsInstanceValid(reference), а чтобы не обращаться к уже запланированному на удаление объекту — также reference.IsQueuedForDeletion(). Это особенно важно после await или смены уровня.

Если результат отличается от примера

СимптомЧто проверить сначала
Изменения кода не появилисьСохраните файл и дождитесь успешного Build Project; работающая старая сборка не подтверждает новую
Rotator ready не появляетсяСкрипт прикреплён к кубу, класс называется Rotator, содержит partial, сборка без ошибок
Скорость в коде другая, но куб вращается по-старомуСмотрите сохранённое значение Degrees Per Second в инспекторе
_Ready() не повторяется после возврата объектаЭто тот же экземпляр; для каждого входа используйте _EnterTree()
NullReferenceException / ошибка поиска дочернего объектаСверьте имя, регистр, тип и относительный путь; найдите первую строку своего скрипта в стеке
Ошибка обращения после удаленияПроверяйте действительность native-объекта, а не только reference != null

SDK и сборка из командной строки

Поставка содержит .NET 10 и пакет Reckfell.NET.Sdk/1.0.0.

Сгенерированный .csproj использует такую основу:

XML
<Project Sdk="Reckfell.NET.Sdk/1.0.0">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <EnableDynamicLoading>true</EnableDynamicLoading>
  </PropertyGroup>
</Project>

Для сборки из папки проекта выполните dotnet build через dotnet.exe из поставки. Требуются локальные пакеты Reckfell. После обновления SDK пересоберите проект.

Ошибки сборки и прикрепления скрипта: решение проблем.

Инструменты кода

Подсказки Roslyn, поиск использований и отладка описаны во встроенной IDE. Логику можно также создавать в SharpGraph и преобразовывать в отдельные редактируемые файлы C#.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.