Add new Level.PreloadSceneAsync for streaming levels before they need to be loaded in
This commit is contained in:
@@ -27,6 +27,17 @@ API_STRUCT(NoDefault) struct FLAXENGINE_API SceneReference
|
|||||||
{
|
{
|
||||||
return ID != other.ID;
|
return ID != other.ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE SceneReference& operator=(const Guid& id)
|
||||||
|
{
|
||||||
|
ID = id;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE operator Guid() const
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ enum class SceneEventType
|
|||||||
OnSceneLoadError = 5,
|
OnSceneLoadError = 5,
|
||||||
OnSceneUnloading = 6,
|
OnSceneUnloading = 6,
|
||||||
OnSceneUnloaded = 7,
|
OnSceneUnloaded = 7,
|
||||||
|
OnScenePreloaded = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SceneResult
|
enum class SceneResult
|
||||||
@@ -117,6 +118,11 @@ public:
|
|||||||
{
|
{
|
||||||
return SceneResult::Failed;
|
return SceneResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool IsPreloading(const Guid* sceneId = nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -147,6 +153,13 @@ struct TimeSlicer
|
|||||||
class SceneLoader
|
class SceneLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum class Modes
|
||||||
|
{
|
||||||
|
Sync,
|
||||||
|
Async,
|
||||||
|
Preload,
|
||||||
|
};
|
||||||
|
|
||||||
struct Args
|
struct Args
|
||||||
{
|
{
|
||||||
rapidjson_flax::Value& Data;
|
rapidjson_flax::Value& Data;
|
||||||
@@ -172,6 +185,7 @@ public:
|
|||||||
|
|
||||||
bool AsyncLoad;
|
bool AsyncLoad;
|
||||||
bool AsyncJobs;
|
bool AsyncJobs;
|
||||||
|
bool Preload;
|
||||||
Guid SceneId = Guid::Empty;
|
Guid SceneId = Guid::Empty;
|
||||||
Scene* Scene = nullptr;
|
Scene* Scene = nullptr;
|
||||||
float TotalTime = 0.0f;
|
float TotalTime = 0.0f;
|
||||||
@@ -185,9 +199,10 @@ public:
|
|||||||
SceneObjectsFactory::PrefabSyncData* PrefabSyncData = nullptr;
|
SceneObjectsFactory::PrefabSyncData* PrefabSyncData = nullptr;
|
||||||
TimeSlicer StageSlicer;
|
TimeSlicer StageSlicer;
|
||||||
|
|
||||||
SceneLoader(bool asyncLoad = false)
|
SceneLoader(Modes mode = Modes::Sync)
|
||||||
: AsyncLoad(asyncLoad)
|
: AsyncLoad(mode != Modes::Sync)
|
||||||
, AsyncJobs(JobSystem::GetThreadsCount() > 1)
|
, AsyncJobs(JobSystem::GetThreadsCount() > 1)
|
||||||
|
, Preload(mode == Modes::Preload)
|
||||||
, Modifier(Cache::ISerializeModifier.GetUnscoped())
|
, Modifier(Cache::ISerializeModifier.GetUnscoped())
|
||||||
, Context(Modifier)
|
, Context(Modifier)
|
||||||
{
|
{
|
||||||
@@ -221,6 +236,8 @@ public:
|
|||||||
SceneResult OnInitialize(Args& args);
|
SceneResult OnInitialize(Args& args);
|
||||||
SceneResult OnBeginPlay(Args& args);
|
SceneResult OnBeginPlay(Args& args);
|
||||||
SceneResult OnEnd(Args& args);
|
SceneResult OnEnd(Args& args);
|
||||||
|
|
||||||
|
static bool LoadPreloadedScene(::Scene* scene);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace LevelImpl
|
namespace LevelImpl
|
||||||
@@ -228,6 +245,7 @@ namespace LevelImpl
|
|||||||
Array<SceneAction*> _sceneActions;
|
Array<SceneAction*> _sceneActions;
|
||||||
CriticalSection _sceneActionsLocker;
|
CriticalSection _sceneActionsLocker;
|
||||||
DateTime _lastSceneLoadTime(0);
|
DateTime _lastSceneLoadTime(0);
|
||||||
|
Array<Scene*> _preloadedScenes;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
Array<ScriptsReloadObject> ScriptsReloadObjects;
|
Array<ScriptsReloadObject> ScriptsReloadObjects;
|
||||||
#endif
|
#endif
|
||||||
@@ -290,6 +308,7 @@ Delegate<Scene*, const Guid&> Level::SceneLoaded;
|
|||||||
Delegate<Scene*, const Guid&> Level::SceneLoadError;
|
Delegate<Scene*, const Guid&> Level::SceneLoadError;
|
||||||
Delegate<Scene*, const Guid&> Level::SceneUnloading;
|
Delegate<Scene*, const Guid&> Level::SceneUnloading;
|
||||||
Delegate<Scene*, const Guid&> Level::SceneUnloaded;
|
Delegate<Scene*, const Guid&> Level::SceneUnloaded;
|
||||||
|
Delegate<Scene*, const Guid&> Level::ScenePreloaded;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
Action Level::ScriptsReloadStart;
|
Action Level::ScriptsReloadStart;
|
||||||
Action Level::ScriptsReload;
|
Action Level::ScriptsReload;
|
||||||
@@ -523,8 +542,8 @@ public:
|
|||||||
AssetReference<JsonAsset> SceneAsset;
|
AssetReference<JsonAsset> SceneAsset;
|
||||||
SceneLoader Loader;
|
SceneLoader Loader;
|
||||||
|
|
||||||
LoadSceneAction(const Guid& sceneId, JsonAsset* sceneAsset, bool async)
|
LoadSceneAction(const Guid& sceneId, JsonAsset* sceneAsset, SceneLoader::Modes mode)
|
||||||
: Loader(async)
|
: Loader(mode)
|
||||||
{
|
{
|
||||||
SceneId = sceneId;
|
SceneId = sceneId;
|
||||||
SceneAsset = sceneAsset;
|
SceneAsset = sceneAsset;
|
||||||
@@ -538,6 +557,11 @@ public:
|
|||||||
return SceneResult::Wait;
|
return SceneResult::Wait;
|
||||||
return LevelImpl::loadScene(Loader, SceneAsset, &context.TimeBudget);
|
return LevelImpl::loadScene(Loader, SceneAsset, &context.TimeBudget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPreloading(const Guid* sceneId) override
|
||||||
|
{
|
||||||
|
return Loader.Preload && (!sceneId || *sceneId == SceneId);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnloadSceneAction : public SceneAction
|
class UnloadSceneAction : public SceneAction
|
||||||
@@ -817,6 +841,9 @@ void LevelImpl::CallSceneEvent(SceneEventType eventType, Scene* scene, Guid scen
|
|||||||
case SceneEventType::OnSceneUnloaded:
|
case SceneEventType::OnSceneUnloaded:
|
||||||
Level::SceneUnloaded(scene, sceneId);
|
Level::SceneUnloaded(scene, sceneId);
|
||||||
break;
|
break;
|
||||||
|
case SceneEventType::OnScenePreloaded:
|
||||||
|
Level::ScenePreloaded(scene, sceneId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,6 +980,7 @@ bool LevelImpl::unloadScene(Scene* scene)
|
|||||||
scene->EndPlay();
|
scene->EndPlay();
|
||||||
|
|
||||||
// Remove from scenes list
|
// Remove from scenes list
|
||||||
|
_preloadedScenes.Remove(scene);
|
||||||
Level::Scenes.Remove(scene);
|
Level::Scenes.Remove(scene);
|
||||||
|
|
||||||
// Fire event
|
// Fire event
|
||||||
@@ -967,12 +995,36 @@ bool LevelImpl::unloadScene(Scene* scene)
|
|||||||
bool LevelImpl::unloadScenes()
|
bool LevelImpl::unloadScenes()
|
||||||
{
|
{
|
||||||
PROFILE_MEM(Level);
|
PROFILE_MEM(Level);
|
||||||
|
|
||||||
|
// Preloading actions
|
||||||
|
_sceneActionsLocker.Lock();
|
||||||
|
for (int32 i = _sceneActions.Count() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
auto action = _sceneActions[i];
|
||||||
|
if (action->IsPreloading())
|
||||||
|
{
|
||||||
|
_sceneActions.RemoveAtKeepOrder(i--);
|
||||||
|
Delete(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_sceneActionsLocker.Unlock();
|
||||||
|
|
||||||
|
// Preloaded scenes
|
||||||
|
auto preloadedScenes = _preloadedScenes;
|
||||||
|
for (auto scene : preloadedScenes)
|
||||||
|
{
|
||||||
|
if (unloadScene(scene))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active scenes
|
||||||
auto scenes = Level::Scenes;
|
auto scenes = Level::Scenes;
|
||||||
for (int32 i = scenes.Count() - 1; i >= 0; i--)
|
for (int32 i = scenes.Count() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (unloadScene(scenes[i]))
|
if (unloadScene(scenes[i]))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,7 +1096,7 @@ SceneResult LevelImpl::loadScene(SceneLoader& loader, rapidjson_flax::Value& dat
|
|||||||
const float delta = time.GetTotalSeconds();
|
const float delta = time.GetTotalSeconds();
|
||||||
loader.TotalTime += delta;
|
loader.TotalTime += delta;
|
||||||
timeLeft -= delta;
|
timeLeft -= delta;
|
||||||
if (timeLeft < 0.0f && result == SceneResult::Success)
|
if (timeLeft < 0.0f && result == SceneResult::Success && loader.Stage != SceneLoader::Stages::Loaded)
|
||||||
{
|
{
|
||||||
result = SceneResult::Wait;
|
result = SceneResult::Wait;
|
||||||
break;
|
break;
|
||||||
@@ -1391,6 +1443,15 @@ SceneResult SceneLoader::OnInitialize(Args& args)
|
|||||||
|
|
||||||
SceneResult SceneLoader::OnBeginPlay(Args& args)
|
SceneResult SceneLoader::OnBeginPlay(Args& args)
|
||||||
{
|
{
|
||||||
|
if (Preload)
|
||||||
|
{
|
||||||
|
// Scene got preloaded
|
||||||
|
_preloadedScenes.Add(Scene);
|
||||||
|
CallSceneEvent(SceneEventType::OnScenePreloaded, Scene, SceneId);
|
||||||
|
LOG(Info, "Scene pre-loaded in {}ms ({} frames)", (int32)(TotalTime * 1000.0), Engine::UpdateCount - StartFrame);
|
||||||
|
Stage = Stages::Loaded;
|
||||||
|
return SceneResult::Success;
|
||||||
|
}
|
||||||
PROFILE_CPU_NAMED("BeginPlay");
|
PROFILE_CPU_NAMED("BeginPlay");
|
||||||
ASSERT_LOW_LAYER(IsInMainThread());
|
ASSERT_LOW_LAYER(IsInMainThread());
|
||||||
|
|
||||||
@@ -1449,6 +1510,24 @@ SceneResult SceneLoader::OnEnd(Args& args)
|
|||||||
return SceneResult::Success;
|
return SceneResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SceneLoader::LoadPreloadedScene(::Scene* scene)
|
||||||
|
{
|
||||||
|
PROFILE_CPU_NAMED("BeginPlay");
|
||||||
|
ASSERT_LOW_LAYER(IsInMainThread());
|
||||||
|
|
||||||
|
// Link scene
|
||||||
|
ScopeLock lock(Level::ScenesLock);
|
||||||
|
_preloadedScenes.Remove(scene);
|
||||||
|
Level::Scenes.Add(scene);
|
||||||
|
|
||||||
|
// Start the game for scene objects
|
||||||
|
SceneBeginData beginData;
|
||||||
|
scene->BeginPlay(&beginData);
|
||||||
|
beginData.OnDone();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool LevelImpl::saveScene(Scene* scene)
|
bool LevelImpl::saveScene(Scene* scene)
|
||||||
{
|
{
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -1657,6 +1736,33 @@ bool Level::LoadScene(const Guid& id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check preloaded scenes
|
||||||
|
for (auto scene : _preloadedScenes)
|
||||||
|
{
|
||||||
|
if (scene->GetID() == id)
|
||||||
|
return SceneLoader::LoadPreloadedScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if scene is during preloading
|
||||||
|
_sceneActionsLocker.Lock();
|
||||||
|
for (auto action : _sceneActions)
|
||||||
|
{
|
||||||
|
if (action->IsPreloading(&id))
|
||||||
|
{
|
||||||
|
// Turn preloading into loading and run it now
|
||||||
|
auto loadAction = (LoadSceneAction*)action;
|
||||||
|
loadAction->Loader.Preload = false;
|
||||||
|
if (loadScene(loadAction->Loader, loadAction->SceneAsset) != SceneResult::Success)
|
||||||
|
{
|
||||||
|
LOG(Error, "Failed to deserialize scene {0}", id);
|
||||||
|
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_sceneActionsLocker.Unlock();
|
||||||
|
|
||||||
// Preload scene asset
|
// Preload scene asset
|
||||||
const auto sceneAsset = Content::LoadAsync<JsonAsset>(id);
|
const auto sceneAsset = Content::LoadAsync<JsonAsset>(id);
|
||||||
if (sceneAsset == nullptr)
|
if (sceneAsset == nullptr)
|
||||||
@@ -1705,8 +1811,98 @@ bool Level::LoadSceneAsync(const Guid& id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check preloaded scenes
|
||||||
|
// TODO: if scene loader gets time-slicing to begin play then make a new action to perform it in async
|
||||||
|
for (auto scene : _preloadedScenes)
|
||||||
|
{
|
||||||
|
if (scene->GetID() == id)
|
||||||
|
return SceneLoader::LoadPreloadedScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if scene is during preloading
|
||||||
|
_sceneActionsLocker.Lock();
|
||||||
|
for (auto action : _sceneActions)
|
||||||
|
{
|
||||||
|
if (action->IsPreloading(&id))
|
||||||
|
{
|
||||||
|
// Turn preloading into loading and let it load this scene (it might be in progress already)
|
||||||
|
auto loadAction = (LoadSceneAction*)action;
|
||||||
|
loadAction->Loader.Preload = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_sceneActionsLocker.Unlock();
|
||||||
|
|
||||||
ScopeLock lock(_sceneActionsLocker);
|
ScopeLock lock(_sceneActionsLocker);
|
||||||
_sceneActions.Enqueue(New<LoadSceneAction>(id, sceneAsset, true));
|
_sceneActions.Enqueue(New<LoadSceneAction>(id, sceneAsset, SceneLoader::Modes::Async));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Level::PreloadSceneAsync(const Guid& id)
|
||||||
|
{
|
||||||
|
if (!id.IsValid())
|
||||||
|
{
|
||||||
|
Log::ArgumentException();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check preloaded scenes
|
||||||
|
for (auto scene : _preloadedScenes)
|
||||||
|
{
|
||||||
|
if (scene->GetID() == id)
|
||||||
|
return false; // Already preloaded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check queue
|
||||||
|
_sceneActionsLocker.Lock();
|
||||||
|
for (auto action : _sceneActions)
|
||||||
|
{
|
||||||
|
if (action->IsPreloading(&id))
|
||||||
|
return false; // Already preloading
|
||||||
|
}
|
||||||
|
_sceneActionsLocker.Unlock();
|
||||||
|
|
||||||
|
// Preload scene asset
|
||||||
|
const auto sceneAsset = Content::LoadAsync<JsonAsset>(id);
|
||||||
|
if (sceneAsset == nullptr)
|
||||||
|
{
|
||||||
|
LOG(Error, "Cannot load scene asset.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopeLock lock(_sceneActionsLocker);
|
||||||
|
_sceneActions.Enqueue(New<LoadSceneAction>(id, sceneAsset, SceneLoader::Modes::Preload));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Level::UnloadScene(const Guid& id)
|
||||||
|
{
|
||||||
|
// Try with already loaded scene
|
||||||
|
if (Scene* scene = FindScene(id))
|
||||||
|
return unloadScene(scene);
|
||||||
|
|
||||||
|
// Check preloaded scenes
|
||||||
|
for (auto scene : _preloadedScenes)
|
||||||
|
{
|
||||||
|
if (scene->GetID() == id)
|
||||||
|
return unloadScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check loading queue
|
||||||
|
_sceneActionsLocker.Lock();
|
||||||
|
for (int32 i = _sceneActions.Count() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
auto action = _sceneActions[i];
|
||||||
|
if (action->IsPreloading(&id))
|
||||||
|
{
|
||||||
|
_sceneActions.RemoveAtKeepOrder(i--);
|
||||||
|
Delete(action);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_sceneActionsLocker.Unlock();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace FlaxEngine
|
|||||||
public static bool ChangeSceneAsync(Guid sceneAssetId)
|
public static bool ChangeSceneAsync(Guid sceneAssetId)
|
||||||
{
|
{
|
||||||
UnloadAllScenesAsync();
|
UnloadAllScenesAsync();
|
||||||
return LoadSceneAsync(sceneAssetId);
|
return Internal_LoadSceneAsync(ref sceneAssetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -34,7 +34,7 @@ namespace FlaxEngine
|
|||||||
/// <returns>True if action fails (given asset is not a scene asset, missing data, scene loading error), otherwise false.</returns>
|
/// <returns>True if action fails (given asset is not a scene asset, missing data, scene loading error), otherwise false.</returns>
|
||||||
public static bool LoadScene(SceneReference sceneAsset)
|
public static bool LoadScene(SceneReference sceneAsset)
|
||||||
{
|
{
|
||||||
return LoadScene(sceneAsset.ID);
|
return Internal_LoadScene(ref sceneAsset.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -44,7 +44,30 @@ namespace FlaxEngine
|
|||||||
/// <returns>True if failed (given asset is not a scene asset, missing data), otherwise false.</returns>
|
/// <returns>True if failed (given asset is not a scene asset, missing data), otherwise false.</returns>
|
||||||
public static bool LoadSceneAsync(SceneReference sceneAsset)
|
public static bool LoadSceneAsync(SceneReference sceneAsset)
|
||||||
{
|
{
|
||||||
return LoadSceneAsync(sceneAsset.ID);
|
return Internal_LoadSceneAsync(ref sceneAsset.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begins preloading scene in the background. Intended to use by scene streaming systems that want to prepare scene but not add to the level yet.
|
||||||
|
/// Loads scene asset, deserializes actors and scripts, setup objects hierarchy with transformations and initializes them (incl. calling OnAwake for scripts).
|
||||||
|
/// Preloaded scene is not added to the loaded scenes and not active in the game (no BeginPlay/OnEnable/OnStart called yet). Use <see cref="LoadScene(Guid)"/> or <see cref="LoadSceneAsync(Guid)"/> to finish loading preloaded scene and add it to the level.
|
||||||
|
/// Preloaded scene can be normally unloaded via <see cref="UnloadScene(Guid)"/> to release resources if it's not needed anymore.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sceneAsset">The asset with the scene to preload.</param>
|
||||||
|
/// <returns>True if preloading cannot be done, otherwise false.</returns>
|
||||||
|
public static bool PreloadSceneAsync(SceneReference sceneAsset)
|
||||||
|
{
|
||||||
|
return Internal_PreloadSceneAsync(ref sceneAsset.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unloads given scene.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sceneAsset">The asset with the scene to unload.</param>
|
||||||
|
/// <returns>True if action cannot be done, otherwise false.</returns>
|
||||||
|
public static bool UnloadScene(SceneReference sceneAsset)
|
||||||
|
{
|
||||||
|
return Internal_UnloadScene(ref sceneAsset.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -222,6 +222,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_EVENT() static Delegate<Scene*, const Guid&> SceneUnloaded;
|
API_EVENT() static Delegate<Scene*, const Guid&> SceneUnloaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when scene gets preloaded (loaded but not yet added to the level).
|
||||||
|
/// </summary>
|
||||||
|
API_EVENT() static Delegate<Scene*, const Guid&> ScenePreloaded;
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -316,35 +321,52 @@ public:
|
|||||||
/// <returns>True if loading cannot be done, otherwise false.</returns>
|
/// <returns>True if loading cannot be done, otherwise false.</returns>
|
||||||
API_FUNCTION() static bool LoadSceneAsync(const Guid& id);
|
API_FUNCTION() static bool LoadSceneAsync(const Guid& id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begins preloading scene in the background. Intended to use by scene streaming systems that want to prepare scene but not add to the level yet.
|
||||||
|
/// Loads scene asset, deserializes actors and scripts, setup objects hierarchy with transformations and initializes them (incl. calling OnAwake for scripts).
|
||||||
|
/// Preloaded scene is not added to the loaded scenes and not active in the game (no BeginPlay/OnEnable/OnStart called yet). Use <see cref="LoadScene(Guid)"/> or <see cref="LoadSceneAsync(Guid)"/> to finish loading preloaded scene and add it to the level.
|
||||||
|
/// Preloaded scene can be normally unloaded via <see cref="UnloadScene(Guid)"/> to release resources if it's not needed anymore.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Scene ID</param>
|
||||||
|
/// <returns>True if preloading cannot be done, otherwise false.</returns>
|
||||||
|
API_FUNCTION() static bool PreloadSceneAsync(const Guid& id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads given scene.
|
/// Unloads given scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="id">Scene ID</param>
|
||||||
|
/// <returns>True if action cannot be done, otherwise false.</returns>
|
||||||
|
API_FUNCTION() static bool UnloadScene(const Guid& id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unloads given scene.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scene">Scene</param>
|
||||||
/// <returns>True if action cannot be done, otherwise false.</returns>
|
/// <returns>True if action cannot be done, otherwise false.</returns>
|
||||||
API_FUNCTION() static bool UnloadScene(Scene* scene);
|
API_FUNCTION() static bool UnloadScene(Scene* scene);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads given scene. Done in the background.
|
/// Unloads given scene. Done in the background.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="scene">Scene</param>
|
||||||
API_FUNCTION() static void UnloadSceneAsync(Scene* scene);
|
API_FUNCTION() static void UnloadSceneAsync(Scene* scene);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads all scenes.
|
/// Unloads all scenes. Cancels all scene preloading.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if action cannot be done, otherwise false.</returns>
|
/// <returns>True if action cannot be done, otherwise false.</returns>
|
||||||
API_FUNCTION() static bool UnloadAllScenes();
|
API_FUNCTION() static bool UnloadAllScenes();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads all scenes. Done in the background.
|
/// Unloads all scenes. Done in the background. Cancels all scene preloading.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FUNCTION() static void UnloadAllScenesAsync();
|
API_FUNCTION() static void UnloadAllScenesAsync();
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reloads scripts. Done in the background.
|
/// Reloads scripts. Done in the background.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void ReloadScriptsAsync();
|
static void ReloadScriptsAsync();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
Reference in New Issue
Block a user