ILoadManager

Для обработки процесса загрузки сохранения игры SaveManager0 требует реализацию в наследнике SaveManager этого интерфейса ILoadManager, но не прямо, а посредством реализации его в классе World. Ниже показан сам интерфейс, и пример его реализации в World.

public interface ILoadManager
{
    // Должен предоставить интерфейс IObject, например его реализует компонент ItemCreate
    IObject IObject { get;}

    /// Все объекты в игре с уникальными Id
    Dictionary<int, GameObject> AllObject { get; }

    // Сбрасывает игру до начального состояния перед загрузкой сохранения
    // Как правило реализуется в корне игры классе World
    // Нет реализации по умолчанию
    public void ResetGame();

    /// Восстанавливает производные данные и все процессы после загрузки сохранения
    // Как правило реализуется в корне игры классе World
    // Нет реализации по умолчанию
    public void RecoverGame();

    #region default 
    // Создать объект с идентификатором argObjectId из префаба с названием argModelName     
    // Есть реализация по умолчанию
    public GameObject CreatePrefab(int argObjectId, string argModelName) { ...  }

    // Добавить объект argObject с уникальным идентификатором argObjectId
    // Есть реализация по умолчанию
    public void AddObject(int argObjectId, GameObject argObject) { ... }

    /// Получить объект по уникальному идентификатору argId
    // Есть реализация по умолчанию
    public GameObject GetObject(int argId) { ... }

    // Минимальный сброс текущей игры, например, вызывает DestroyWorld()
    // Есть реализация по умолчанию
    public void ResetGameInner() { ... }

    // Уничтожение текущего мира - удаляет все объект в уровнях мира IObject.WorldLevel
    // Есть реализация по умолчанию 
    public void DestroyWorld() { ... }

    // Сбросить события, т.е. удалить все подписки на событие argEventName у объекта 
    // Есть реализация по умолчанию
    public void ResetEvent(object argObject, string argEventName) { ... }
    #endregion
}

Теперь World должен наследоваться от Item, т.к. компонент сохранения дореализует (см. линковка) у класса Item два интерфейса с полным поведением по умолчанию IPrefabId и IDataSave. Первый требуется для возможности идентификации объекта, а второй используется для создания протокола данных, которые подлежат сохранению.

public partial class World : Item, ILoadManager
{
    #region ILoadManager
    // Здесь будут хранится все объекты добавленные в процессе загрузки из файла сохранения
    // и этот словарь будет использоваться для обмена ссылками на соответтвующие объекты по универсальному идентификатору (ключу словаря)
    private Dictionary<int, GameObject> allObject = new Dictionary<int, GameObject>();
    public Dictionary<int, GameObject> AllObject { get { return allObject; } }
    // Как правило World изначально использует компонент ItemCreate, поэтому реализацию интерфейса IObject можно предоставить ему
    public IObject IObject { get { return ItemCreate; } }

    // Будет вызвано перед загрузкой из файла сохранеия, для сброса текущей игры,
    // используйте реализацию по умолчанию ResetGameInner() чтобы удалить объекты из уровней игры, расположенных в сцене и сбросьте
    // все события с помощью ResetEvent, на которые могли быть подписаны объекты прошлой игры, которые не пересоздаются, например, DayNight
    public void ResetGame()
    {
        (this as ILoadManager).ResetGameInner();
        (this as ILoadManager).ResetEvent(DayNight, "NextDay");
        (this as ILoadManager).ResetEvent(DayNight, "NextHour");
        ...
    }

    // Будет вызвано после загрузки из файла сохранения, для востановления записанной игры с прерванного момента,
    // Используйте для повторной инициализации объектов, которые этого требует (их метод Start после загрузки вызван не будет),
    // переподпишитесь на нужные события, обновите NavMesh в соответствии с изменениями в сцене, перезапустите, если требуется короутины,
    public void RecoverGame()
    {
        RunPanel.Init(DayNight, Society);
        DayNight.NextHour += AgentWalkEmulation;

        UpdateSurface();
        ...
    }
    #endregion
}