// 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(); } } }