forked from KhronosGroup/UnityGLTF
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ryan Green
committed
Jul 3, 2024
1 parent
4c50cf2
commit 9e8aa39
Showing
2 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Runtime.ExceptionServices; | ||
using System.Threading.Tasks; | ||
using UnityEngine; | ||
using UnityEngine.Events; | ||
using UnityGLTF.Loader; | ||
using UnityGLTF.Plugins; | ||
|
||
namespace UnityGLTF | ||
{ | ||
/// <summary> | ||
/// Component to load a GLTF scene with | ||
/// </summary> | ||
public class GLTFSpaceComponent : MonoBehaviour | ||
{ | ||
public string GLTFUri = null; | ||
public bool Multithreaded = true; | ||
public bool UseStream = false; | ||
public bool AppendStreamingAssets = true; | ||
public bool PlayAnimationOnLoad = true; | ||
[Tooltip("Hide the scene object during load, then activate it when complete")] | ||
public bool HideSceneObjDuringLoad = false; | ||
public ImporterFactory Factory = null; | ||
public UnityAction onLoadComplete; | ||
|
||
#if UNITY_ANIMATION | ||
public IEnumerable<Animation> Animations { get; private set; } | ||
#endif | ||
|
||
[SerializeField] | ||
private bool loadOnStart = false; | ||
|
||
[SerializeField] private int RetryCount = 10; | ||
[SerializeField] private float RetryTimeout = 2.0f; | ||
private int numRetries = 0; | ||
|
||
|
||
public int MaximumLod = 300; | ||
public int Timeout = 8; | ||
public GLTFSceneImporter.ColliderType Collider = GLTFSceneImporter.ColliderType.None; | ||
public GameObject LastLoadedScene { get; private set; } = null; | ||
|
||
[SerializeField] | ||
private Shader shaderOverride = null; | ||
|
||
[Header("Import Settings")] | ||
public GLTFImporterNormals ImportNormals = GLTFImporterNormals.Import; | ||
public GLTFImporterNormals ImportTangents = GLTFImporterNormals.Import; | ||
public bool SwapUVs = false; | ||
[Tooltip("Blend shape frame weight import multiplier. Default is 1. For compatibility with some FBX animations you may need to use 100.")] | ||
public BlendShapeFrameWeightSetting blendShapeFrameWeight = new BlendShapeFrameWeightSetting(BlendShapeFrameWeightSetting.MultiplierOption.Multiplier1); | ||
|
||
private async void Start() | ||
{ | ||
if (!loadOnStart) return; | ||
|
||
try | ||
{ | ||
await Load(); | ||
} | ||
#if WINDOWS_UWP | ||
catch (Exception) | ||
#else | ||
catch (HttpRequestException) | ||
#endif | ||
{ | ||
if (numRetries++ >= RetryCount) | ||
throw; | ||
|
||
Debug.LogWarning("Load failed, retrying"); | ||
await Task.Delay((int)(RetryTimeout * 1000)); | ||
Start(); | ||
} | ||
} | ||
|
||
public async Task Load() | ||
{ | ||
var importOptions = new ImportOptions | ||
{ | ||
AsyncCoroutineHelper = gameObject.GetComponent<AsyncCoroutineHelper>() ?? gameObject.AddComponent<AsyncCoroutineHelper>(), | ||
ImportNormals = ImportNormals, | ||
ImportTangents = ImportTangents, | ||
SwapUVs = SwapUVs | ||
}; | ||
|
||
var settings = GLTFSettings.GetOrCreateSettings(); | ||
for (var i = settings.ImportPlugins.Count - 1; i >= 0; i--) | ||
{ | ||
Debug.Log($"{nameof(GLTFSpaceComponent)} plugin: {settings.ImportPlugins[i].DisplayName}"); | ||
} | ||
|
||
importOptions.ImportContext = new GLTFImportContext(settings); | ||
|
||
GLTFSceneImporter sceneImporter = null; | ||
try | ||
{ | ||
if (!Factory) Factory = ScriptableObject.CreateInstance<DefaultImporterFactory>(); | ||
|
||
// UseStream is currently not supported... | ||
string fullPath; | ||
if (AppendStreamingAssets) | ||
fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar })); | ||
else | ||
fullPath = GLTFUri; | ||
|
||
string dir = URIHelper.GetDirectoryName(fullPath); | ||
importOptions.DataLoader = new UnityWebRequestLoader(dir); | ||
sceneImporter = Factory.CreateSceneImporter( | ||
Path.GetFileName(fullPath), | ||
|
||
importOptions | ||
); | ||
|
||
sceneImporter.SceneParent = gameObject.transform; | ||
sceneImporter.Collider = Collider; | ||
sceneImporter.MaximumLod = MaximumLod; | ||
sceneImporter.Timeout = Timeout; | ||
sceneImporter.IsMultithreaded = Multithreaded; | ||
sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; | ||
|
||
// for logging progress | ||
await sceneImporter.LoadSceneAsync( | ||
showSceneObj: !HideSceneObjDuringLoad, | ||
onLoadComplete: LoadCompleteAction | ||
// ,progress: new Progress<ImportProgress>( | ||
// p => | ||
// { | ||
// Debug.Log("Progress: " + p); | ||
// }) | ||
); | ||
|
||
// Override the shaders on all materials if a shader is provided | ||
if (shaderOverride != null) | ||
{ | ||
Renderer[] renderers = gameObject.GetComponentsInChildren<Renderer>(); | ||
foreach (Renderer renderer in renderers) | ||
{ | ||
renderer.sharedMaterial.shader = shaderOverride; | ||
} | ||
} | ||
|
||
LastLoadedScene = sceneImporter.LastLoadedScene; | ||
|
||
if (HideSceneObjDuringLoad) | ||
LastLoadedScene.SetActive(true); | ||
|
||
#if UNITY_ANIMATION | ||
Animations = sceneImporter.LastLoadedScene.GetComponents<Animation>(); | ||
|
||
if (PlayAnimationOnLoad && Animations.Any()) | ||
{ | ||
Animations.First().Play(); | ||
} | ||
#endif | ||
} | ||
catch(Exception e) | ||
{ | ||
Debug.LogError($"Error loading space: {e.Message}"); | ||
LastLoadedScene = null; | ||
onLoadComplete?.Invoke(); | ||
} | ||
finally | ||
{ | ||
if (importOptions.DataLoader != null) | ||
{ | ||
sceneImporter?.Dispose(); | ||
sceneImporter = null; | ||
importOptions.DataLoader = null; | ||
} | ||
} | ||
} | ||
|
||
private void LoadCompleteAction(GameObject obj, ExceptionDispatchInfo exceptionDispatchInfo) | ||
{ | ||
onLoadComplete?.Invoke(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.