// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors
// SPDX-License-Identifier: Apache-2.0
using System.Threading.Tasks;
using UnityEngine;
namespace GLTFast
{
using Logging;
using Loading;
using Materials;
///
/// Base component for code-less loading of glTF files
///
public abstract class GltfAssetBase : MonoBehaviour
{
[SerializeField]
ImportSettings importSettings;
///
public ImportSettings ImportSettings
{
get => importSettings;
set => importSettings = value;
}
///
/// Instance used for loading the glTF's content
///
// ReSharper disable once MemberCanBeProtected.Global
public GltfImport Importer { get; protected set; }
///
/// Indicates whether the glTF was loaded (no matter if successfully or not)
///
/// True when loading routine ended, false otherwise.
public bool IsDone => Importer != null && Importer.LoadingDone;
///
/// Scene ID of the recently instantiated scene. Null if there was no
/// scene instantiated (successfully).
///
public int? CurrentSceneId { get; protected set; }
///
/// Method for manual loading with custom and .
///
/// URL of the glTF file.
/// Download Provider for custom loading (e.g. caching or HTTP authorization)
/// Defer Agent takes care of interrupting the
/// loading procedure in order to keep the frame rate responsive.
/// Used to convert glTF materials to instances
/// Used for message reporting
/// Async Task that loads the glTF's contents
public virtual async Task Load(
string gltfUrl,
IDownloadProvider downloadProvider = null,
IDeferAgent deferAgent = null,
IMaterialGenerator materialGenerator = null,
ICodeLogger logger = null
)
{
Importer = new GltfImport(downloadProvider, deferAgent, materialGenerator, logger);
return await Importer.Load(gltfUrl, importSettings);
}
///
/// Creates an instance of the main scene
///
/// Used for message reporting
/// True if instantiation was successful.
// ReSharper disable once MemberCanBeProtected.Global
public async Task Instantiate(ICodeLogger logger = null)
{
if (Importer == null) return false;
var instantiator = GetDefaultInstantiator(logger);
var success = await Importer.InstantiateMainSceneAsync(instantiator);
PostInstantiation(instantiator, success);
return success;
}
///
/// Creates an instance of the scene specified by the scene index.
///
/// Index of the scene to be instantiated
/// Used for message reporting
/// True if instantiation was successful.
public virtual async Task InstantiateScene(int sceneIndex, ICodeLogger logger = null)
{
if (Importer == null) return false;
var instantiator = GetDefaultInstantiator(logger);
var success = await Importer.InstantiateSceneAsync(instantiator, sceneIndex);
PostInstantiation(instantiator, success);
return success;
}
///
/// Creates an instance of the scene specified by the scene index.
///
/// Index of the scene to be instantiated
/// Receives scene construction calls
/// True if instantiation was successful.
protected async Task InstantiateScene(int sceneIndex, GameObjectInstantiator instantiator)
{
if (Importer == null) return false;
var success = await Importer.InstantiateSceneAsync(instantiator, sceneIndex);
PostInstantiation(instantiator, success);
return success;
}
///
/// Removes previously instantiated scene(s)
///
public abstract void ClearScenes();
///
/// Returns an imported glTF material.
/// Note: Asset has to have finished loading before!
///
/// Index of material in glTF file.
/// glTF material if it was loaded successfully and index is correct, null otherwise.
public Material GetMaterial(int index = 0)
{
return Importer?.GetMaterial(index);
}
///
/// Number of scenes loaded
///
public int SceneCount => Importer?.SceneCount ?? 0;
///
/// Array of scenes' names (entries can be null, if not specified)
///
public string[] SceneNames
{
get
{
if (Importer != null && Importer.SceneCount > 0)
{
var names = new string[Importer.SceneCount];
for (int i = 0; i < names.Length; i++)
{
names[i] = Importer.GetSceneName(i);
}
return names;
}
return null;
}
}
///
/// Returns an instance of the default instantiator
///
/// Custom logger to use with the instantiator
/// Default instantiator instance
protected abstract IInstantiator GetDefaultInstantiator(ICodeLogger logger);
///
/// Callback that is called after instantiation
///
/// instantiator that was used
/// True if instantiation was successful, false otherwise
protected virtual void PostInstantiation(IInstantiator instantiator, bool success)
{
CurrentSceneId = success ? Importer.DefaultSceneIndex : null;
}
///
/// Releases previously allocated resources.
///
// ReSharper disable once MemberCanBePrivate.Global
public void Dispose()
{
if (Importer != null)
{
Importer.Dispose();
Importer = null;
}
}
///
/// Called before GameObject is destroyed
///
protected virtual void OnDestroy()
{
Dispose();
}
}
}