Я працював над чимось дуже схожим для свого поточного проекту. Це швидкий аналіз того, як я це роблю, з деякими побічними зауваженнями про те, як зробити речі трохи простішими на собі.
Для мене першою проблемою було розбиття світу на менші шматки, які було б доречно завантажувати та розвантажувати на льоту. Оскільки ви використовуєте карту на основі плитки, цей крок стає значно простішим. Замість того, щоб розглядати положення кожного 3D-об’єкта на рівні, ви вже маєте рівень, який добре розділений на плитки. Це дозволяє вам просто розбити світ на X відрізками плитки Y і завантажити їх.
Ви хочете зробити це автоматично, а не вручну. Оскільки ви використовуєте XNA, у вас є можливість використовувати контент-конвеєр із спеціальним експортером для вмісту рівня. Якщо ви не знаєте, як запустити процес експорту без перекомпіляції, я щиро рекомендую проти цього. Хоча C # не так повільно збирається, як звичайно C ++, ви все одно не хочете завантажувати Visual Studio і перекомпілювати свою гру кожного разу, коли ви вносите незначну зміну на карту.
Ще одна важлива річ - переконатися, що ви використовуєте правильну схему іменування для файлів, що містять фрагменти вашого рівня. Ви хочете мати можливість знати, що ви хочете завантажити або вивантажити фрагмент C, а потім генерувати ім'я файлу, яке потрібно завантажити, щоб зробити це під час виконання. Нарешті, придумайте будь-які дрібниці, які можуть допомогти вам у дорозі. Дійсно, що можна змінити, наскільки великий шматок, реекспортувати, а потім побачити наслідки цього на продуктивність негайно.
На час виконання, це все ще досить просто. Вам знадобиться якийсь спосіб асинхронно завантажувати та вивантажувати шматки, але це дуже залежить від того, як працює ваша гра чи движок. Ваше друге зображення є точно правильним - вам потрібно визначити, які шматки потрібно завантажувати чи вивантажувати, і зробити відповідні запити, щоб це було так, якщо його ще немає. Залежно від того, скільки шматочків ви завантажили за один раз, ви можете це робити щоразу, коли гравець перетне межу від однієї частини до іншої. Зрештою, у будь-якому випадку, ви хочете переконатися, що достатньо завантажено, що навіть у найгірший (розумний) час завантаження шматок все ще завантажується до того, як гравець зможе це побачити. Ви, мабуть, захочете багато пограти з цим номером, поки не отримаєте хороший баланс між продуктивністю та витратою пам'яті.
Що стосується фактичної архітектури, вам потрібно буде абстрагувати процес фактичного завантаження та вивантаження даних із пам'яті з процесу визначення того, що слід завантажувати / вивантажувати. Для вашої першої ітерації я б навіть не переймався ефективністю завантаження / вивантаження, а просто отримав найпростішу річ, яка могла б працювати, і гарантую, що ви генеруєте відповідні запити у відповідний час. Після цього ви можете переглянути оптимізацію завантаження, щоб мінімізувати сміття.
У мене виникли багато додаткових складностей завдяки двигуну, який я використовував, але це досить специфічно для реалізації. Якщо у вас виникнуть запитання щодо того, що я зробив, будь ласка, прокоментуйте, і я зроблю все, що можу, щоб допомогти.