AssetViewerBase.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using System;
  2. using TriLibCore.General;
  3. using TriLibCore.Utils;
  4. using UnityEngine;
  5. using UnityEngine.Networking;
  6. using UnityEngine.UI;
  7. namespace TriLibCore.Samples
  8. {
  9. /// <summary>Represents a base class used in TriLib samples.</summary>
  10. public class AssetViewerBase : MonoBehaviour
  11. {
  12. /// <summary>Gets the Asset Viewer Singleton instance.</summary>
  13. public static AssetViewerBase Instance { get; private set; }
  14. /// <summary>
  15. /// Model/skybox loading bar. (Used on platforms with async capabilities)
  16. /// </summary>
  17. [SerializeField]
  18. private RectTransform _loadingBar;
  19. /// <summary>
  20. /// Help box wrapper.
  21. /// </summary>
  22. [SerializeField]
  23. private GameObject _helpWrapper;
  24. /// <summary>
  25. /// Loading screen wrapper. (Used on platforms without async capabilities)
  26. /// </summary>
  27. [SerializeField]
  28. private GameObject _loadingWrapper;
  29. /// <summary>
  30. /// Model URL loading dialog.
  31. /// </summary>
  32. [SerializeField]
  33. private GameObject _modelUrlDialog;
  34. /// <summary>
  35. /// Model URL loading Input Field.
  36. /// </summary>
  37. [SerializeField]
  38. private InputField _modelUrl;
  39. /// <summary>
  40. /// Animation playback slider.
  41. /// </summary>
  42. [SerializeField]
  43. protected Slider PlaybackSlider;
  44. /// <summary>
  45. /// Animation playback time.
  46. /// </summary>
  47. [SerializeField]
  48. protected Text PlaybackTime;
  49. /// <summary>
  50. /// Animation selector.
  51. /// </summary>
  52. [SerializeField]
  53. protected Dropdown PlaybackAnimation;
  54. /// <summary>
  55. /// Play button.
  56. /// </summary>
  57. [SerializeField]
  58. protected Selectable Play;
  59. /// <summary>
  60. /// Stop button.
  61. /// </summary>
  62. [SerializeField]
  63. protected Selectable Stop;
  64. /// <summary>
  65. /// Options used in this sample.
  66. /// </summary>
  67. protected AssetLoaderOptions AssetLoaderOptions;
  68. /// <summary>
  69. /// Current camera pitch and yaw angles.
  70. /// </summary>
  71. public Vector2 CameraAngle;
  72. /// <summary>
  73. /// Loaded game object.
  74. /// </summary>
  75. public GameObject RootGameObject { get; protected set; }
  76. /// <summary>
  77. /// Mouse input multiplier.
  78. /// Higher values will make the mouse movement more sensible.
  79. /// </summary>
  80. protected const float InputMultiplierRatio = 0.1f;
  81. /// <summary>
  82. /// Maximum camera pitch and light pitch (rotation around local X-axis).
  83. /// </summary>
  84. protected const float MaxPitch = 80f;
  85. /// <summary>Updates the Camera based on mouse Input.</summary>
  86. protected void UpdateCamera()
  87. {
  88. CameraAngle.x = Mathf.Repeat(CameraAngle.x + Input.GetAxis("Mouse X"), 360f);
  89. CameraAngle.y = Mathf.Clamp(CameraAngle.y + Input.GetAxis("Mouse Y"), -MaxPitch, MaxPitch);
  90. }
  91. /// <summary>
  92. /// Shows the help box.
  93. /// </summary>
  94. public void ShowHelp()
  95. {
  96. _helpWrapper.SetActive(true);
  97. }
  98. /// <summary>
  99. /// Hides the help box.
  100. /// </summary>
  101. public void HideHelp()
  102. {
  103. _helpWrapper.SetActive(false);
  104. }
  105. /// <summary>
  106. /// Shows the model URL dialog.
  107. /// </summary>
  108. public void ShowModelUrlDialog()
  109. {
  110. _modelUrlDialog.SetActive(true);
  111. _modelUrl.Select();
  112. _modelUrl.ActivateInputField();
  113. }
  114. /// <summary>
  115. /// Hides the model URL dialog.
  116. /// </summary>
  117. public void HideModelUrlDialog()
  118. {
  119. _modelUrlDialog.SetActive(false);
  120. _modelUrl.text = null;
  121. }
  122. /// <summary>
  123. /// Shows the file picker for loading a model from local file-system.
  124. /// </summary>
  125. protected void LoadModelFromFile(GameObject wrapperGameObject = null, Action<AssetLoaderContext> onMaterialsLoad = null)
  126. {
  127. SetLoading(false);
  128. var filePickerAssetLoader = AssetLoaderFilePicker.Create();
  129. filePickerAssetLoader.LoadModelFromFilePickerAsync("Select a File", OnLoad, onMaterialsLoad ?? OnMaterialsLoad, OnProgress, OnBeginLoadModel, OnError, wrapperGameObject ?? gameObject, AssetLoaderOptions);
  130. }
  131. /// <summary>Loads a model from a URL.</summary>
  132. protected void LoadModelFromURL(UnityWebRequest request, string fileExtension, GameObject wrapperGameObject = null, object customData = null, Action<AssetLoaderContext> onMaterialsLoad = null)
  133. {
  134. HideModelUrlDialog();
  135. SetLoading(true);
  136. OnBeginLoadModel(true);
  137. var isZipFile = fileExtension == "zip";
  138. AssetDownloader.LoadModelFromUri(request, OnLoad, onMaterialsLoad ?? OnMaterialsLoad, OnProgress, OnError, wrapperGameObject, AssetLoaderOptions, customData, isZipFile ? null : fileExtension, isZipFile);
  139. }
  140. /// <summary>
  141. /// Shows the URL selector for loading a model from network.
  142. /// </summary>
  143. public void LoadModelFromURLWithDialogValues()
  144. {
  145. if (string.IsNullOrWhiteSpace(_modelUrl.text))
  146. {
  147. return;
  148. }
  149. var request = AssetDownloader.CreateWebRequest(_modelUrl.text);
  150. var fileExtension = FileUtils.GetFileExtension(request.uri.Segments[request.uri.Segments.Length - 1], false);
  151. LoadModelFromURL(request, fileExtension);
  152. }
  153. /// <summary>Event triggered when the user selects a file or cancels the Model selection dialog.</summary>
  154. /// <param name="hasFiles">If any file has been selected, this value is <c>true</c>, otherwise it is <c>false</c>.</param>
  155. protected virtual void OnBeginLoadModel(bool hasFiles)
  156. {
  157. if (hasFiles)
  158. {
  159. if (RootGameObject != null)
  160. {
  161. Destroy(RootGameObject);
  162. }
  163. SetLoading(true);
  164. }
  165. }
  166. /// <summary>
  167. /// Enables/disables the loading flag.
  168. /// </summary>
  169. /// <param name="value">The new loading flag.</param>
  170. protected void SetLoading(bool value)
  171. {
  172. var selectables = FindObjectsOfType<Selectable>();
  173. foreach (var button in selectables)
  174. {
  175. button.interactable = !value;
  176. }
  177. #if UNITY_WSA || UNITY_WEBGL
  178. _loadingWrapper.gameObject.SetActive(value);
  179. #else
  180. _loadingBar.gameObject.SetActive(value);
  181. #endif
  182. }
  183. /// <summary>Checks if the Dispatcher instance exists and stores this class instance as the Singleton.</summary>
  184. protected virtual void Start()
  185. {
  186. Dispatcher.CheckInstance();
  187. PasteManager.CheckInstance();
  188. Instance = this;
  189. }
  190. /// <summary>Event is triggered when the Model loading progress changes.</summary>
  191. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the information used during the Model loading process, which is available to almost every Model processing method</param>
  192. /// <param name="value">The loading progress, ranging from 0 to 1.</param>
  193. protected virtual void OnProgress(AssetLoaderContext assetLoaderContext, float value)
  194. {
  195. _loadingBar.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, Screen.width * value);
  196. }
  197. /// <summary>Event is triggered when any error occurs.</summary>
  198. /// <param name="contextualizedError">The Contextualized Error that has occurred.</param>
  199. protected virtual void OnError(IContextualizedError contextualizedError)
  200. {
  201. Debug.LogError(contextualizedError);
  202. RootGameObject = null;
  203. SetLoading(false);
  204. }
  205. /// <summary>Event is triggered when the Model Meshes and hierarchy are loaded.</summary>
  206. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the information used during the Model loading process, which is available to almost every Model processing method</param>
  207. protected virtual void OnLoad(AssetLoaderContext assetLoaderContext)
  208. {
  209. }
  210. /// <summary>Event is triggered when the Model (including Textures and Materials) has been fully loaded.</summary>
  211. /// <param name="assetLoaderContext">The Asset Loader Context reference. Asset Loader Context contains the information used during the Model loading process, which is available to almost every Model processing method</param>
  212. protected virtual void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
  213. {
  214. SetLoading(false);
  215. }
  216. /// <summary>
  217. /// Plays the selected animation.
  218. /// </summary>
  219. public virtual void PlayAnimation()
  220. {
  221. }
  222. /// <summary>Stops playing the selected animation.</summary>
  223. public virtual void StopAnimation()
  224. {
  225. }
  226. /// <summary>Switches to the animation selected on the Dropdown.</summary>
  227. /// <param name="index">The selected Animation index.</param>
  228. public virtual void PlaybackAnimationChanged(int index)
  229. {
  230. }
  231. /// <summary>
  232. /// Event triggered when the animation slider value has been changed by the user.
  233. /// </summary>
  234. /// <param name="value">The Animation playback normalized position.</param>
  235. public virtual void PlaybackSliderChanged(float value)
  236. {
  237. }
  238. }
  239. }