Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Assets/Gothic-Core/Scripts/Adapters/Scenes/WorldScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ await _vobService.CreateWorldVobsAsync(_configService.Dev, _loadingService, _sav
Logger.LogError(e.ToString(), LogCat.Loading);
}

// The culling sweep inside WorldSceneLoaded only _enqueued_ all VOBs around the spawn point for
// lazy initialization. InitVobCoroutine() drains the queue in the background while the player is
// already in the world - a brief pop-in is preferred over holding the loading screen any longer.
_loadingService.StopLoading();
SceneManager.UnloadSceneAsync(Constants.SceneLoading);
}
Expand Down
1 change: 1 addition & 0 deletions Assets/Gothic-Core/Scripts/Adapters/Vob/VobLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public class VobLoader : MonoBehaviour
{
public VobContainer Container;
public bool IsLoaded;
public bool IsQueued;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,12 @@ private GameObject GetPrefab(IVirtualObject vob, GameObject parent = null)
go = _resourceCacheService.TryGetPrefabObject(PrefabType.VobSwitch, name: name, parent: parent);
break;
case VirtualObjectType.oCMobDoor:
go = _resourceCacheService.TryGetPrefabObject(PrefabType.VobDoor, name: name, parent: parent);
var visualName = vob.Visual?.Name;
var isBed = !visualName.IsNullOrEmpty()
&& visualName.Split('_')[0].EqualsIgnoreCase("BED");
go = isBed
? _resourceCacheService.TryGetPrefabObject(PrefabType.VobBed, name: name, parent: parent)
: _resourceCacheService.TryGetPrefabObject(PrefabType.VobDoor, name: name, parent: parent);
break;
case VirtualObjectType.oCMobContainer:
go = _resourceCacheService.TryGetPrefabObject(PrefabType.VobContainer, name: name, parent: parent);
Expand Down
47 changes: 29 additions & 18 deletions Assets/Gothic-Core/Scripts/Services/Vobs/VobService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public class VobService
private readonly char[] _itemCountSeparators = { ':', '.' };


private const int VobInitBatchSize = 10;

private Dictionary<VirtualObjectType, GameObject> _vobTypeParentGOs = new();
private Queue<VobLoader> _objectsToInitQueue = new();

Expand Down Expand Up @@ -138,16 +140,14 @@ public void InitVob(GameObject go)
{
go.TryGetComponent(out VobLoader loaderComp);

if (loaderComp == null || loaderComp.IsLoaded)
// IsQueued ensures we do not add elements to be loaded twice (without an O(n) Queue.Contains() check).
if (loaderComp == null || loaderComp.IsLoaded || loaderComp.IsQueued)
{
return;
}

// Do not add elements to be loaded twice.
if (_objectsToInitQueue.Contains(loaderComp))
return;

_objectsToInitQueue.Enqueue(go.GetComponent<VobLoader>());
loaderComp.IsQueued = true;
_objectsToInitQueue.Enqueue(loaderComp);
}

// DEBUG - Check how many frames it took to initialize all the objects
Expand Down Expand Up @@ -175,19 +175,27 @@ private IEnumerator InitVobCoroutine()
// firstFrameQueueFilledUp = Time.frameCount;
// }

var item = _objectsToInitQueue.Dequeue();

item.IsLoaded = true;

// We assume that each loaded VOB is centered at parent=0,0,0.
// Should work smoothly until we start lazy loading sub-vobs ;-)
try
{
_initializerDomain.InitVob(item.Container.Vob, item.gameObject, default, true);
}
catch (Exception e)
for (var i = 0; i < VobInitBatchSize && !_objectsToInitQueue.IsEmpty(); i++)
{
Logger.LogError($"Failed to init VOB {item.name}: {e}", LogCat.Vob);
var item = _objectsToInitQueue.Dequeue();

// Destroyed in the meantime (e.g. world change).
if (item == null)
continue;

item.IsLoaded = true;

// We assume that each loaded VOB is centered at parent=0,0,0.
// Should work smoothly until we start lazy loading sub-vobs ;-)
try
{
_initializerDomain.InitVob(item.Container.Vob, item.gameObject, default, true);
}
catch (Exception e)
{
Logger.LogError($"Failed to init VOB {item.name}: {e}", LogCat.Vob);
}

}

yield return _frameSkipperService.TrySkipToNextFrameCoroutine();
Expand Down Expand Up @@ -242,6 +250,9 @@ private void PreCreateWorldVobs(List<IVirtualObject> vobs, GameObject rootGo, Lo
// We reset the GO dictionary.
_vobTypeParentGOs = new();

// Drop pending lazy-init entries from a previous world. Their VobLoader GOs are destroyed by now.
_objectsToInitQueue.Clear();

ObjectRoutines.ClearAndReleaseMemory();
ObjectRoutines = new();

Expand Down
17 changes: 10 additions & 7 deletions ProjectSettings/ProjectSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PlayerSettings:
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4
defaultScreenOrientation: 3
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
Expand All @@ -17,8 +17,8 @@ PlayerSettings:
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
m_ShowUnitySplashScreen: 1
m_ShowUnitySplashLogo: 1
m_ShowUnitySplashScreen: 0
m_ShowUnitySplashLogo: 0
m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1
m_SplashScreenLogoStyle: 1
Expand Down Expand Up @@ -285,7 +285,7 @@ PlayerSettings:
AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0
androidUseCustomKeystore: 1
androidUseCustomKeystore: 0
m_AndroidBanners:
- width: 320
height: 180
Expand Down Expand Up @@ -536,7 +536,7 @@ PlayerSettings:
- m_BuildTarget: LuminSupport
m_GraphicsJobs: 0
- m_BuildTarget: AndroidPlayer
m_GraphicsJobs: 0
m_GraphicsJobs: 1
- m_BuildTarget: WebGLSupport
m_GraphicsJobs: 0
m_BuildTargetGraphicsJobMode:
Expand All @@ -560,6 +560,9 @@ PlayerSettings:
- m_BuildTarget: WindowsStandaloneSupport
m_APIs: 0200000012000000
m_Automatic: 0
- m_BuildTarget: LinuxStandaloneSupport
m_APIs: 1500000011000000
m_Automatic: 0
m_BuildTargetVRSettings:
- m_BuildTarget: Standalone
m_Enabled: 0
Expand Down Expand Up @@ -875,8 +878,8 @@ PlayerSettings:
webWasm2023: 0
webEnableSubmoduleStrippingCompatibility: 0
scriptingDefineSymbols:
Android: USE_INPUT_SYSTEM_POSE_CONTROL;ENABLE_UBERLOGGING;GOTHIC_HVR_INSTALLED;SENTIS_ANALYTICS_ENABLED;APP_UI_EDITOR_ONLY
Standalone: USE_INPUT_SYSTEM_POSE_CONTROL;ENABLE_UBERLOGGING;GOTHIC_HVR_INSTALLED;SENTIS_ANALYTICS_ENABLED;APP_UI_EDITOR_ONLY
Android: USE_INPUT_SYSTEM_POSE_CONTROL;ENABLE_UBERLOGGING;GOTHIC_HVR_INSTALLED;APP_UI_EDITOR_ONLY
Standalone: USE_INPUT_SYSTEM_POSE_CONTROL;ENABLE_UBERLOGGING;GOTHIC_HVR_INSTALLED;APP_UI_EDITOR_ONLY
Windows Store Apps: USE_INPUT_SYSTEM_POSE_CONTROL
additionalCompilerArguments: {}
platformArchitecture: {}
Expand Down
2 changes: 1 addition & 1 deletion ProjectSettings/QualitySettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ QualitySettings:
- Android
m_TextureMipmapLimitGroupNames: []
m_PerPlatformDefaultQuality:
Android: 1
Android: 0
Lumin: 2
Nintendo 3DS: 2
Nintendo Switch: 2
Expand Down