Skip to content
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2782809
ISSDescriptor initial implementation
dalkia May 14, 2026
be6d9dc
Removing depency on asset bundle version
dalkia May 14, 2026
3d2309a
ISS proto - descriptor-driven LOD, GLTF ISS flag, AB v49 gate
dalkia May 15, 2026
0caf229
ISS LOD - descriptor-mode AB URL, asset name, failure accounting
dalkia May 18, 2026
9e66ef8
ISS bridge slots tracked by descriptor
dalkia May 18, 2026
b05ca70
Revert "ISS bridge slots tracked by descriptor"
dalkia May 18, 2026
2bcadee
Revert "Revert "ISS bridge slots tracked by descriptor""
dalkia May 18, 2026
3714605
ISS - consolidate scene-lifetime state on ISSDescriptor
dalkia May 18, 2026
68909b9
ISS - lazy descriptor resolution via dedicated AssetPromise loader
dalkia May 18, 2026
d4d3dd7
ISS - IISSDescriptor interface bridges asmdef boundary; drop singleto…
dalkia May 19, 2026
75fb3f7
ISS - disk-cached descriptors, hardcoded S3 URL, resolved-state guard
dalkia May 19, 2026
8fb69bc
Merge branch 'dev' into chore/new-iss
dalkia May 19, 2026
3b8133b
FIX TEST
dalkia May 19, 2026
bfcb556
ISS - digest-aware GLTF cache key for LOD↔SDK bridging
dalkia May 21, 2026
a996d2c
Merge branch 'dev' into chore/new-iss
dalkia May 21, 2026
922340b
Merge branch 'dev' into chore/new-iss
dalkia May 26, 2026
c1cd356
Debugging isISS
dalkia May 22, 2026
5b98d46
Deleted unneded straming assets
dalkia May 26, 2026
9f2c181
ISS - remove leftover JUANI debug logs
dalkia May 27, 2026
2dbbf60
ISS - remove EarlySceneRequestSystem and EarlyAssetBundleRequestSystem
dalkia May 27, 2026
2484cb7
ISS - force Descriptor mode, skip Bundle-mode HEAD probe
dalkia May 27, 2026
b2d52ad
ISS - move ISS-capable check to AssetBundleManifestVersion.SupportsISS
dalkia May 27, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public void FinalizeAssetBundleEmoteLoadingCorrectly()
Entity emoteEntity = CreateEmoteEntityWithPromise<AssetBundleData, GetAssetBundleIntention>(mockEmote, intention, bodyShape, out AssetBundlePromise promise);

// Mocking promise result
var assetBundleData = new AssetBundleData(null, null, new []{mockGameObject}, null, null);
var assetBundleData = new AssetBundleData(null, new []{mockGameObject}, null, null);
var promiseResult = new StreamableLoadingResult<AssetBundleData>(assetBundleData);
world.Add(promise.Entity, promiseResult);

Expand Down Expand Up @@ -303,7 +303,7 @@ public void FinalizeAssetBundleEmoteLoadingUnisexCorrectly()
Entity emoteEntity = CreateEmoteEntityWithPromise<AssetBundleData, GetAssetBundleIntention>(mockEmote, intention, loadingBodyShape, out AssetBundlePromise promise);
Entity resultHolderEntity = promise.Entity;

var assetBundleData = new AssetBundleData(null, null, new []{mockGameObject}, null, null);
var assetBundleData = new AssetBundleData(null, new []{mockGameObject}, null, null);
world.Add(resultHolderEntity, new StreamableLoadingResult<AssetBundleData>(assetBundleData));

system.Update(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using ECS.SceneLifeCycle.SceneDefinition;
using ECS.SceneLifeCycle.Systems;
using ECS.StreamableLoading.AssetBundles;
using ECS.StreamableLoading.AssetBundles.InitialSceneState;
using ECS.StreamableLoading.AudioClips;
using ECS.StreamableLoading.DeferredLoading;
using ECS.StreamableLoading.GLTF;
Expand Down Expand Up @@ -42,6 +43,7 @@ static GlobalDeferredLoadingSystem()
{
CreateQuery<GetSceneDefinitionList, SceneDefinitions>(),
CreateQuery<GetSceneDefinition, SceneEntityDefinition>(),
CreateQuery<GetISSDescriptor, ISSDescriptor>(),
CreateQuery<GetSceneFacadeIntention, ISceneFacade>(),
CreateQuery<GetWearableDTOByPointersIntention, WearablesDTOList>(),
CreateQuery<GetTrimmedWearableByParamIntention, IWearable[]>(),
Expand All @@ -59,7 +61,8 @@ static GlobalDeferredLoadingSystem()
COMPONENT_HANDLERS_SCENES = new[]
{
CreateQuery<GetSceneDefinitionList, SceneDefinitions>(),
CreateQuery<GetSceneDefinition, SceneEntityDefinition>()
CreateQuery<GetSceneDefinition, SceneEntityDefinition>(),
CreateQuery<GetISSDescriptor, ISSDescriptor>(),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using DCL.Ipfs;
using DCL.Multiplayer.Emotes;
using DCL.Multiplayer.Profiles.Bunches;
using DCL.SceneRunner.Scene;
using NUnit.Framework;
using SceneRunner.Scene;
using System;
Expand Down Expand Up @@ -330,7 +329,7 @@ private class MockSceneData : ISceneData
{
public bool SceneLoadingConcluded { get; set; } = true;

public IInitialSceneState InitialSceneStateInfo { get; } = new ISceneData.FakeInitialSceneState();
public DCL.SceneRunner.Scene.IISSDescriptor? ISSDescriptor => null;
public SceneShortInfo SceneShortInfo { get; set; } = new (Vector2Int.zero, "mockScene");
public IReadOnlyList<Vector2Int> Parcels { get; set; } = new List<Vector2Int>();
public ISceneContent SceneContent => new SceneNonHashedContent(URLDomain.FromString("file://mock/"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using DCL.Ipfs;
using ECS.SceneLifeCycle.IncreasingRadius;
using ECS.StreamableLoading.AssetBundles;
using ECS.StreamableLoading.AssetBundles.InitialSceneState;
using ECS.StreamableLoading.Common;
using Org.BouncyCastle.Utilities.Collections;
using System;
using System.Collections.Generic;
Expand All @@ -27,6 +29,26 @@ public struct SceneDefinitionComponent

public int InternalJobIndex { get; set; }

/// <summary>
/// Initial Scene State descriptor for this scene. Defaults to <see cref="ISSDescriptor.NONE"/>;
/// populated by <c>ResolveISSDescriptorSystem</c> once the lazy promise resolves. Read in [Query]
/// systems (UpdateSceneLODInfoSystem, ResolveISSLODSystem) that don't have an ISceneData handle.
/// </summary>
public ISSDescriptor ISSDescriptor;

/// <summary>
/// In-flight ISS descriptor promise — <c>AssetPromise.NULL</c> while either no promise is active
/// or the promise has been consumed and the result stashed into <see cref="ISSDescriptor"/>.
/// </summary>
public AssetPromise<ISSDescriptor, GetISSDescriptor> ISSDescriptorPromise;

/// <summary>
/// True once the descriptor promise has resolved (to a real descriptor OR to NONE). Lets
/// <c>ResolveISSDescriptorSystem</c> distinguish "not started" from "resolved-to-NONE" — both
/// of which leave <see cref="ISSDescriptor"/> as the NONE singleton.
/// </summary>
public bool ISSDescriptorResolved;


public float EstimatedMemoryUsageInMB;
public float EstimatedMemoryUsageForLODMB;
Expand All @@ -47,6 +69,9 @@ public SceneDefinitionComponent(
SceneGeometry = sceneGeometry;
InternalJobIndex = -1;
IsPortableExperience = isPortableExperience;
ISSDescriptor = ISSDescriptor.NONE;
ISSDescriptorPromise = AssetPromise<ISSDescriptor, GetISSDescriptor>.NULL;
ISSDescriptorResolved = false;

EstimatedMemoryUsageInMB = Mathf.Clamp(parcels.Count * 15, 0, SceneLoadingMemoryConstants.MAX_SCENE_SIZE);
EstimatedMemoryUsageForLODMB = (EstimatedMemoryUsageInMB / SceneLoadingMemoryConstants.LOD_REDUCTION) + (EstimatedMemoryUsageInMB / SceneLoadingMemoryConstants.QUALITY_REDUCTED_LOD_REDUCTION);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Arch.Core;
using Arch.Core;
using Arch.SystemGroups;
using Arch.SystemGroups.DefaultSystemGroups;
using CommunicationData.URLHelpers;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Arch.Core;
using Arch.System;
using Arch.SystemGroups;
using DCL.Diagnostics;
using ECS.Abstract;
using ECS.LifeCycle.Components;
using ECS.Prioritization.Components;
using ECS.SceneLifeCycle;
using ECS.StreamableLoading.AssetBundles.InitialSceneState;
using ECS.StreamableLoading.Common;
using ECS.StreamableLoading.Common.Components;

namespace ECS.SceneLifeCycle.SceneDefinition
{
/// <summary>
/// Bridges <see cref="LoadISSDescriptorSystem"/> to <see cref="SceneDefinitionComponent"/>: lazily
/// spawns the resolver promise for each scene definition and writes the resolved descriptor onto
/// the component. Global-world systems (UpdateSceneLODInfoSystem, ResolveISSLODSystem) iterate
/// <see cref="SceneDefinitionComponent.ISSDescriptor"/> directly and don't need to know the
/// resolver exists. The scene-runtime path (LoadSceneSystemLogicBase) creates its own promise and
/// gets the same instance via the loader's ongoing-request dedup, so AttachAssetBundle on its side
/// mutates the same descriptor that ends up on this component.
/// </summary>
[UpdateInGroup(typeof(RealmGroup))]
[LogCategory(ReportCategory.SCENE_LOADING)]
public partial class ResolveISSDescriptorSystem : BaseUnityLoopSystem
{
internal ResolveISSDescriptorSystem(World world) : base(world) { }

protected override void Update(float t)
{
SpawnPromiseQuery(World);
ConsumePromiseQuery(World);
}

[Query]
[None(typeof(DeleteEntityIntention))]
private void SpawnPromise(ref SceneDefinitionComponent sceneDefinitionComponent, ref PartitionComponent partition)
{
// Skip if already resolved (NONE or otherwise) or a promise is already in flight.
if (sceneDefinitionComponent.ISSDescriptorResolved) return;
if (sceneDefinitionComponent.ISSDescriptorPromise.Entity != Entity.Null) return;

sceneDefinitionComponent.ISSDescriptorPromise = AssetPromise<ISSDescriptor, GetISSDescriptor>.Create(
World, GetISSDescriptor.For(sceneDefinitionComponent.Definition), partition);
}

[Query]
[None(typeof(DeleteEntityIntention))]
private void ConsumePromise(ref SceneDefinitionComponent sceneDefinitionComponent)
{
if (sceneDefinitionComponent.ISSDescriptorPromise.Entity == Entity.Null) return;

if (!sceneDefinitionComponent.ISSDescriptorPromise.TryConsume(World, out StreamableLoadingResult<ISSDescriptor> result))
return;

sceneDefinitionComponent.ISSDescriptor = result is { Succeeded: true } ? result.Asset! : ISSDescriptor.NONE;
sceneDefinitionComponent.ISSDescriptorPromise = AssetPromise<ISSDescriptor, GetISSDescriptor>.NULL;
sceneDefinitionComponent.ISSDescriptorResolved = true;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
using Arch.Core;
using Arch.Core;
using System;
using System.Collections.Generic;
using System.Threading;
using CommunicationData.URLHelpers;
using Cysharp.Threading.Tasks;
using DCL.Diagnostics;
using DCL.Ipfs;
using DCL.SceneRunner.Scene;
using DCL.Utility;
using DCL.Utility.Exceptions;
using DCL.WebRequests;
using ECS.Prioritization.Components;
using ECS.SceneLifeCycle.Components;
using ECS.StreamableLoading.AssetBundles;
using ECS.StreamableLoading.AssetBundles.InitialSceneState;
using ECS.StreamableLoading.Common;
using ECS.StreamableLoading.InitialSceneState;
using SceneRunner;
using SceneRunner.Scene;
using SceneRuntime.ScenePermissions;
using AssetBundlePromise = ECS.StreamableLoading.Common.AssetPromise<ECS.StreamableLoading.AssetBundles.AssetBundleData, ECS.StreamableLoading.AssetBundles.GetAssetBundleIntention>;
using ISSDescriptorPromise = ECS.StreamableLoading.Common.AssetPromise<ECS.StreamableLoading.AssetBundles.InitialSceneState.ISSDescriptor, ECS.StreamableLoading.AssetBundles.InitialSceneState.GetISSDescriptor>;

namespace ECS.SceneLifeCycle.Systems
{
Expand Down Expand Up @@ -46,16 +44,19 @@ public async UniTask<ISceneFacade> FlowAsync(World world, ISceneFactory sceneFac
// Fixes possible race conditions with the setup of the scene definition, especially on Hybrid mode (LSD+remote ABs)
await OverrideSceneMetadataAsync(hashedContent, intention, reportCategory, ipfsPath.EntityId, ct);
await UniTask.SwitchToMainThread(ct);
var loadMainCrdt = LoadMainCrdtAsync(hashedContent, reportCategory, ct);
var ISSContainedAssetsPromise = LoadISSAsync(world, definition, ct);

(ReadOnlyMemory<byte> mainCrdt, IInitialSceneState? ISSAssets) = await UniTask.WhenAll(loadMainCrdt, ISSContainedAssetsPromise);
// Both tasks start eagerly so they run concurrently; if ISS is in play, also prefetches the
// shared Bundle-mode AB on the descriptor so the scene's GLTF requests hit the cache.
UniTask<ReadOnlyMemory<byte>> loadMainCrdt = LoadMainCrdtAsync(hashedContent, reportCategory, ct);
UniTask<ISSDescriptor?> loadISS = ResolveAndPrefetchISSAsync(world, definition, partition, ct);
ReadOnlyMemory<byte> mainCrdt = await loadMainCrdt;
ISSDescriptor? issDescriptor = await loadISS;

// Create scene data
var baseParcel = intention.DefinitionComponent.Definition.metadata.scene.DecodedBase;
var sceneData = new SceneData(hashedContent, definitionComponent.Definition, baseParcel,
definitionComponent.SceneGeometry, definitionComponent.Parcels, new StaticSceneMessages(mainCrdt),
ISSAssets);
issDescriptor);

// Launch at the end of the frame
await UniTask.SwitchToMainThread(PlayerLoopTiming.LastPostLateUpdate, ct);
Expand All @@ -69,30 +70,36 @@ public async UniTask<ISceneFacade> FlowAsync(World world, ISceneFactory sceneFac
return sceneFacade;
}

private async UniTask<IInitialSceneState> LoadISSAsync(World world, SceneEntityDefinition sceneDefinitionComponent, CancellationToken ct)
/// <summary>
/// Lazily resolves the ISS descriptor (the loader gates pre-v49 manifests to <see cref="ISSDescriptor.NONE"/>)
/// and, if Bundle mode is selected, eagerly fetches the shared ISS asset bundle and attaches it to
/// the descriptor so it stays cached for the LOD path and SDK GLTF requests rewritten to its URL.
/// Returns the resolved descriptor so the caller can stash it on <see cref="SceneData.ISSDescriptor"/>.
/// </summary>
private async UniTask<ISSDescriptor?> ResolveAndPrefetchISSAsync(World world, SceneEntityDefinition definition, IPartitionComponent partition, CancellationToken ct)
{
if (sceneDefinitionComponent.SupportInitialSceneState())
{
var promise = AssetBundlePromise.Create(world,
GetAssetBundleIntention.FromHash(GetAssetBundleIntention.BuildInitialSceneStateURL(sceneDefinitionComponent.id),
assetBundleManifestVersion: sceneDefinitionComponent.assetBundleManifestVersion,
parentEntityID: sceneDefinitionComponent.id),
PartitionComponent.TOP_PRIORITY);
ISSDescriptorPromise promise = ISSDescriptorPromise.Create(world, GetISSDescriptor.For(definition), partition);
promise = await promise.ToUniTaskAsync(world, cancellationToken: ct);

promise = await promise.ToUniTaskAsync(world, cancellationToken: ct);
ISSDescriptor descriptor = promise.Result is { Succeeded: true } result ? result.Asset! : ISSDescriptor.NONE;

if (promise.Result.Value.Succeeded)
{
var result = new HashSet<string>();
if (descriptor.SupportsBundle())
{
AssetBundlePromise bundlePromise = AssetBundlePromise.Create(world,
GetAssetBundleIntention.FromHash(GetAssetBundleIntention.BuildInitialSceneStateURL(definition.id),
assetBundleManifestVersion: definition.assetBundleManifestVersion,
parentEntityID: definition.id),
PartitionComponent.TOP_PRIORITY);

foreach (string s in promise.Result.Value.Asset.InitialSceneStateMetadata.Value.assetHash)
result.Add($"{s}{PlatformUtils.GetCurrentPlatform()}");
bundlePromise = await bundlePromise.ToUniTaskAsync(world, cancellationToken: ct);

return InitialSceneStateInfo.CreateISS(promise.Result.Value.Asset, result);
}
if (bundlePromise.Result.Value.Succeeded)
descriptor.AttachAssetBundle(bundlePromise.Result.Value.Asset);
}

return InitialSceneStateInfo.CreateEmpty();
// Return null for the NONE singleton so SceneData can store "no ISS" as null rather than
// forwarding the singleton's Dereference no-op through every scene unload.
return descriptor.CurrentState == DCL.SceneRunner.Scene.IISSDescriptor.State.None ? null : descriptor;
}

protected abstract string GetAssetBundleSceneId(string ipfsPathEntityId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,9 @@ private void CompleteEarlySceneRequest(Entity entity, ref ScenePromise promise)
{
if (promise.TryConsume(World, out StreamableLoadingResult<SceneDefinitions> Result))
{
if (Result.Succeeded && Result.Asset.Value.Count > 0)
{
if (Result.Asset.Value[0].SupportInitialSceneState())
{
//Do nothing. We just needed loaded in memory, we dont care the result.
//Whoever needs it, will grab it later
//Test URL
World.Create(EarlyAssetBundleFlag.CreateAssetBundleRequest(Result.Asset.Value[0]));
}
}
// ISS bundle prewarm previously fired here based on the eagerly-resolved descriptor.
// Resolution is lazy now (LOD path / SDK runtime loader), so the prewarm is dropped —
// the bundle is fetched by those paths when they actually need it.

//Nothing to do with it after creation of the early asset bundle request
World.Destroy(entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using ECS.StreamableLoading.Cache;
using ECS.StreamableLoading.Common.Components;
using ECS.StreamableLoading.Common.Systems;
using ECS.StreamableLoading.InitialSceneState;
using Runtime.Wearables;
using SceneRunner;
using SceneRunner.Scene;
Expand Down Expand Up @@ -81,8 +80,7 @@ public LoadSmartWearableSceneSystem(
sceneDefinition.metadata.scene.DecodedBase,
definitionComponent.SceneGeometry,
definitionComponent.Parcels,
new StaticSceneMessages(crdt),
InitialSceneStateInfo.CreateEmpty());
new StaticSceneMessages(crdt));

// Set the flag is we are using the special DTO for builder collection preview
sceneData.IsWearableBuilderCollectionPreview = wearable.DTO is BuilderWearableDTO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,26 @@ public class AssetBundleData : StreamableRefCountData<AssetBundle>
{
private readonly string AssetBundleName;

public readonly InitialSceneStateMetadata? InitialSceneStateMetadata;

private bool AssetBundleUnloaded;
private Dictionary<string, AssetInfo>? Assets;
private readonly AssetBundleData[] Dependencies;

public AssetBundleData(AssetBundle assetBundle, InitialSceneStateMetadata? initialSceneState, Object[] loadedAssets, Type? assetType, AssetBundleData[] dependencies, string version = "", string source = "")
//TODO: Rehook isISS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking regression: isISS is never passed as true from LoadAssetBundleSystem.CreateAssetBundleDataAsync (the only call site), so every ISS bundle gets isISS = false and UnloadAB() is called on it. The original code used !InitialSceneStateMetadata.HasValue to guard the unload — this PR removes that guard without restoring it.

The PR description claims this flag is "plumbed through so ISS bundles aren't unloaded prematurely" but the code contradicts that. The //TODO: Rehook isISS comment confirms it's unfinished.

Wire isISS properly: LoadAssetBundleSystem.CreateAssetBundleDataAsync receives no ISS context right now. A simple fix would be to add an isISS parameter to CreateAssetBundleDataAsync, set by the caller via GetAssetBundleIntention (a new flag on the intention) or by detecting the bundle hash against the ISS URL.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking (unfinished TODO): //TODO: Rehook isISS confirms this isn't wired. LoadAssetBundleSystem.CreateAssetBundleDataAsync (line 170) never passes isISS: true, so every ISS bundle is created with the default false and UnloadAB() is called on it immediately. The PR description says this flag is "plumbed through so ISS bundles aren't unloaded prematurely" — the code contradicts that.

Wire it: add an isISS parameter to CreateAssetBundleDataAsync and detect ISS bundles at the call site (e.g. by checking whether intention.Hash starts with "staticscene_" or by adding an IsISS flag to GetAssetBundleIntention).

public AssetBundleData(AssetBundle assetBundle , Object[] loadedAssets, Type? assetType, AssetBundleData[] dependencies, string version = "", string source = "", bool isISS = false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking (unfinished TODO, 3rd flag): //TODO: Rehook isISS still present. LoadAssetBundleSystem.CreateAssetBundleDataAsync at line 170 still passes no isISS argument, so every ISS bundle is constructed with isISS = false and UnloadAB() fires immediately on all of them. The PR description claims this flag is "plumbed through so ISS bundles aren't unloaded prematurely" — the code contradicts that.

Wire it: add an isISS parameter to CreateAssetBundleDataAsync, detect ISS bundles at the call site (e.g. by checking intention.Hash starts with "staticscene_" or by adding an IsISS flag to GetAssetBundleIntention), and remove the TODO comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking (unfinished TODO, 4th flag): //TODO: Rehook isISS still present and UnloadAB() at line 39 still fires unconditionally for all bundles. LoadAssetBundleSystem.CreateAssetBundleDataAsync (line 170) still never passes isISS: true, so every ISS bundle is constructed with isISS = false and UnloadAB() fires immediately — the ISS bundle is unloaded before any per-asset extraction can happen.

The PR description says this flag is "plumbed through so ISS bundles aren't unloaded prematurely". The code contradicts that claim.

Fix: add an isISS flag to GetAssetBundleIntention (or detect via the staticscene_ hash prefix), thread it through CreateAssetBundleDataAsync, pass isISS: true when constructing AssetBundleData, and uncomment the if (!isISS) guard around UnloadAB(). Remove the TODO comment.

: base(assetBundle, ReportCategory.ASSET_BUNDLES)
{
InitialSceneStateMetadata = initialSceneState;

Assets = new Dictionary<string, AssetInfo>();

for (var i = 0; i < loadedAssets.Length; i++)
Assets[loadedAssets[i].name] = new AssetInfo(loadedAssets[i], assetType ?? loadedAssets[i].GetType(), version, source, InitialSceneStateMetadata.HasValue);
Assets[loadedAssets[i].name] = new AssetInfo(loadedAssets[i], assetType ?? loadedAssets[i].GetType(), version, source, isISS);

Dependencies = dependencies;

//Debugging purposes. Test cases may bring a null AB, therefore we need this check
AssetBundleName = Asset?.name;

//We cannot unload an AB if its an ISS (Initial Scene State AB). It may be a dependency for dynamically isntanced AB
if (!InitialSceneStateMetadata.HasValue)
if (!isISS)
UnloadAB();
}

Expand Down Expand Up @@ -157,10 +154,3 @@ public static TValue FirstValueOrDefaultNonAlloc<TKey, TValue>(this Dictionary<T
}
}

public struct InitialSceneStateMetadata
{
public List<string> assetHash;
public List<Vector3> positions;
public List<Quaternion> rotations;
public List<Vector3> scales;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading