10 — Збереження¶
🇬🇧 English | 🇺🇦 Українська
Плагін не має власної системи збережень — і навмисне. У кожного проєкту вона своя, а плагін, що нав'язує власний формат слотів, зазвичай доводиться обходити.
Замість цього інвентар віддає звичайну структуру, яку ви кладете у свій USaveGame.
Як це виглядає¶
UCLASS()
class UMySaveGame : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY(SaveGame)
FISInventorySaveData Backpack;
UPROPERTY(SaveGame)
FISEquipmentSaveData Loadout;
};
Збереження:
UMySaveGame* Save = Cast<UMySaveGame>(
UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass()));
Save->Backpack = InventoryComponent->ExportState();
Save->Loadout = EquipmentComponent->ExportState();
UGameplayStatics::SaveGameToSlot(Save, TEXT("Slot1"), 0);
Завантаження:
if (UMySaveGame* Save = Cast<UMySaveGame>(
UGameplayStatics::LoadGameFromSlot(TEXT("Slot1"), 0)))
{
InventoryComponent->ImportState(Save->Backpack);
EquipmentComponent->ImportState(Save->Loadout);
}
У Blueprint усе те саме: Export State / Import State — звичайні вузли.
Що саме зберігається¶
| Дані | Як записано |
|---|---|
| Тип предмета | FSoftObjectPath — шлях до ассета, а не вказівник |
| Номер слота | точний індекс, щоб розкладка не змінилася |
| Розмір стеку | як є |
| Стан екземпляра | міцність, заряди, якість — усе з StatValues |
| Кількість слотів | щоб покращений рюкзак завантажився покращеним |
| Ліміт ваги | з тієї ж причини |
Шлях замість вказівника — це те, що дозволяє збереженню пережити перезапуск гри, патч і навіть переміщення ассета (Unreal-редиректори враховуються).
Стан предметів справді зберігається¶
Це не «запам'ятати тип і кількість»:
Меч із міцністю 12/100 → зберегли → завантажили → меч із міцністю 12/100
При завантаженні хуки створення не виконуються — інакше іржавий меч повертався б із
майстерні новеньким. Значення StatValues присвоюються напряму, як відновлені факти, а
не як зміни.
Коли викликати ImportState¶
Тільки після того, як актор-власник повністю ініціалізовано. З конструктора — зарано.
Практично: BeginPlay або момент, коли ваша система збережень готова застосувати дані.
ImportState сам очищає поточний вміст перед відновленням — попереднє очищення не
потрібне.
Що буде, якщо предмета більше не існує¶
Гра оновилася, ассет видалено, а гравець його ніс.
Такий предмет пропускається з попередженням у лог, а решта завантажується нормально. Один вилучений предмет ніколи не коштує гравцеві всього збереження.
ImportState поверне false, повідомляючи, що відновилося не все — це інформація, а не
помилка. Чи показувати щось гравцеві, вирішуєте ви.
Спорядження: дві відмінності¶
Предмети кладуться прямо в слоти, не проходячи через інвентар. Це навмисно: відновлення спорядження не має залежати від того, чи є місце в рюкзаку.
Слоти, яких у персонажа більше немає (схема тіла змінилася між версіями), пропускаються з попередженням.
Порядок при завантаженні обох компонентів:
InventoryComponent->ImportState(Save->Backpack);
EquipmentComponent->ImportState(Save->Loadout);
Спорядження при відновленні спершу скидає поточне без повернення в інвентар — інакше в рюкзаку з'явилися б копії речей, які збереження вже враховує окремо.
Мультиплеєр¶
Обидві функції лише серверні. Виклик на клієнті ігнорується з попередженням.
Це правильно: інвентар авторитетний на сервері, тож і відновлюється там, а клієнти отримують результат звичайною реплікацією.
Якщо ваша гра зберігає прогрес окремо для кожного гравця, викликайте ImportState на
сервері для відповідного PlayerState (або пішака — залежно від того, де ви розмістили
компонент).
Що НЕ зберігається¶
| Не зберігається | Чому і що робити |
|---|---|
Предмети на землі (AISItemPickup) |
Це актори рівня. Зберігайте їх своєю системою збереження світу, або не зберігайте зовсім. |
| Стан скринь | Так само — це актори. Викличте ExportState на ContainerInventory, якщо потрібно. |
| Кулдауни витратних предметів | Навмисно ефемерні; після завантаження предмет доступний одразу. |
| Візуальні актори спорядження | Створюються заново з фрагмента при відновленні слота. |
Скриню зберегти нескладно — її інвентар такий самий:
Save->ChestContents = Container->GetContainerInventory()->ExportState();
Куди далі¶
- Перевірити, що відновилося: 13 — Відлагодження
- Повний перелік структур: 10 — Довідник