reckfellENGINE

Создать экземпляр и сохранить дерево Entity

Parent, Owner и PackedEntity; почему дочерний объект работает в игре, но исчезает после сохранения.

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

Parent и Owner решают разные задачи

Parent задаёт иерархию, наследование преобразований и жизненный цикл дочерних объектов. AddChild добавляет объект в эту иерархию. Owner указывает, какому сохраняемому дереву принадлежит Entity. Он должен быть предком; корню не назначают самого себя владельцем.

В обычном дереве, которое вы строите кодом для сохранения, после AddChild назначайте child.Owner = root. Это не требуется каждому временному снаряду только ради работы в игре. Вложенный экземпляр префаба уже имеет собственные области Owner: не переписывайте их всем потомкам одним циклом.

Проверить сохранение

Добавьте OwnerPackingDemo.cs в C#-проект 1.0.0, прикрепите к Entity отдельного тестового уровня, соберите и нажмите F6. В Output появится Owner packing: Ok; в user:// создастся OwnedExample.rprefab. Откройте папку пользовательских данных проекта и проверьте файл: Saved есть, Transient нет. Пример перезаписывает только указанный учебный файл.

OwnerPackingDemo.cs
C#
using Reckfell;

public partial class OwnerPackingDemo : Entity
{
    public static Error SaveExample(string path)
    {
        if (!path.EndsWith(".rprefab") && !path.EndsWith(".rscene")) return Error.InvalidParameter;
        var root = new Entity2D { Name = "OwnedExample" };
        try
        {
            var saved = new Entity2D { Name = "Saved", Position = new Vector2(12, 34) };
            root.AddChild(saved);
            saved.Owner = root;
            var transient = new Entity { Name = "Transient" };
            root.AddChild(transient);
            using var packed = new PackedEntity();
            Error error = packed.Pack(root);
            return error == Error.Ok ? ResourceSaver.Save(packed, path) : error;
        }
        finally
        {
            root.Free();
        }
    }

    public override void _Ready()
    {
        Error error = SaveExample("user://OwnedExample.rprefab");
        ReckfellApi.Print("Owner packing: " + error);
    }
}

Pack создаёт снимок сериализуемого дерева, а не автоматически сохраняет его на диск. Только после успешного Pack вызывается ResourceSaver.Save. Для загрузки используйте ResourceLoader.Load<PackedEntity>, проверьте результат и CanInstantiate, затем Instantiate. Новый корень ещё не прикреплён: настройте нужные свойства и передайте его в AddChild.

В тесте исходный root освобождается после Pack, а новый экземпляр восстанавливает Saved.Position и Owner. Это отдельные Entity. Другие Resource-ссылки внутри префаба могут оставаться общими: создание Entity не означает глубокую копию всех материалов и текстур.

Почему ребёнок пропал

ПричинаДействие
Есть Parent, но нет нужного OwnerНазначить Owner после добавления к предку
Без Owner оставлен промежуточный контейнерПроверить всю сохраняемую ветку: Pack может пропустить её вместе с потомками
Сохранён другой rootПередать корень того дерева, которое нужно восстановить
Сохранён PackedEntity до изменения объектовПовторить Pack после изменения; он не следит за живым деревом
Вложенный префаб получил чужого OwnerСохранить его собственную структуру и менять только нужные переопределения

PackedEntityState.GetEntityCount считает записи снимка, а не всех потомков, которые появятся после раскрытия вложенных префабов. В примере уровня сохранены три записи — корень и две ссылки на префаб; реальных потомков после Instantiate больше.

Создание и удаление во время игры

_EnterTree вызывается при входе, _Ready — после готовности детей. Если создаваемый объект использует настройки или испускает сигнал в _Ready, задайте их и подключите обработчики до AddChild. Для переиспользуемого объекта не рассчитывайте на повторный _Ready при каждом входе.

QueueFree ставит удаление в очередь; ссылка ещё может существовать до обработки очереди. После освобождения C#-переменная не гарантирует живой native-объект: проверяйте ReckfellObject.IsInstanceValid и не обращайтесь к удалённой Entity. RemoveChild только отсоединяет; он не освобождает объект. За отсоединённым объектом должен остаться владелец жизненного цикла.

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

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

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

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