internal async void OnCreateAsset()

in MREUnityRuntimeLib/Assets/AssetLoader.cs [433:586]


		internal async void OnCreateAsset(CreateAsset payload, Action onCompleteCallback)
		{
			var def = payload.Definition;
			var response = new AssetsLoaded();
			var unityAsset = _app.AssetManager.GetById(def.Id)?.Asset;
			ColliderGeometry colliderGeo = null;
			AssetSource source = null;

			ActiveContainers.Add(payload.ContainerId);

			// create materials
			if (unityAsset == null && def.Material != null)
			{
				unityAsset = UnityEngine.Object.Instantiate(MREAPI.AppsAPI.DefaultMaterial);
			}

			// create textures
			else if (unityAsset == null && def.Texture != null)
			{
				var texUri = new Uri(_app.ServerAssetUri, def.Texture.Value.Uri);
				source = new AssetSource(AssetContainerType.None, texUri.AbsoluteUri);
				var result = await AssetFetcher<UnityEngine.Texture>.LoadTask(_owner, texUri);

				// this is a newly loaded texture, so we decide initial settings for the shared asset
				if (result.ReturnCode == 200)
				{
					result.Asset.wrapModeU = def.Texture.Value.WrapModeU ?? TextureWrapMode.Repeat;
					result.Asset.wrapModeV = def.Texture.Value.WrapModeV ?? TextureWrapMode.Repeat;
					result.Asset.filterMode = FilterMode.Bilinear;
				}

				source.Version = result.ETag;
				unityAsset = result.Asset;
				if (result.FailureMessage != null)
				{
					response.FailureMessage = result.FailureMessage;
				}
			}

			// create meshes
			else if (unityAsset == null && def.Mesh != null)
			{
				if (def.Mesh.Value.PrimitiveDefinition != null)
				{
					var factory = MREAPI.AppsAPI.PrimitiveFactory;
					try
					{
						unityAsset = factory.CreatePrimitive(def.Mesh.Value.PrimitiveDefinition.Value);
						colliderGeo = ConvertPrimToCollider(def.Mesh.Value.PrimitiveDefinition.Value, def.Id);
					}
					catch (Exception e)
					{
						response.FailureMessage = e.Message;
						MREAPI.Logger.LogError(response.FailureMessage);
					}
				}
				else
				{
					response.FailureMessage = $"Cannot create mesh {def.Id} without a primitive definition";
				}
			}

			// create sounds
			else if (unityAsset == null && def.Sound != null)
			{
				var soundUri = new Uri(_app.ServerAssetUri, def.Sound.Value.Uri);
				source = new AssetSource(AssetContainerType.None, soundUri.AbsoluteUri);
				var result = await AssetFetcher<UnityEngine.AudioClip>.LoadTask(_owner, soundUri);
				unityAsset = result.Asset;
				source.Version = result.ETag;
				if (result.FailureMessage != null)
				{
					response.FailureMessage = result.FailureMessage;
				}
			}

			// create video streams
			else if (unityAsset == null && def.VideoStream != null)
			{
				if (MREAPI.AppsAPI.VideoPlayerFactory != null)
				{
					string videoString;

					// These youtube "URIs" are not valid URIs because they are case-sensitive. Don't parse, and
					// deprecate this URL scheme as soon as feasible.
					if (def.VideoStream.Value.Uri.StartsWith("youtube://"))
					{
						videoString = def.VideoStream.Value.Uri;
					}
					else
					{
						var videoUri = new Uri(_app.ServerAssetUri, def.VideoStream.Value.Uri);
						videoString = videoUri.AbsoluteUri;
					}

					PluginInterfaces.FetchResult result2 = MREAPI.AppsAPI.VideoPlayerFactory.PreloadVideoAsset(videoString);
					unityAsset = result2.Asset;
					if (result2.FailureMessage != null)
					{
						response.FailureMessage = result2.FailureMessage;
					}
				}
				else
				{
					response.FailureMessage = "VideoPlayerFactory not implemented";
				}
			}

			// create animation data
			else if (unityAsset == null && def.AnimationData != null)
			{
				var animDataCache = ScriptableObject.CreateInstance<AnimationDataCached>();
				animDataCache.Tracks = def.AnimationData.Value.Tracks;
				unityAsset = animDataCache;
			}

			_app.AssetManager.Set(def.Id, payload.ContainerId, unityAsset, colliderGeo, source);

			// verify creation and apply initial patch
			if (unityAsset != null)
			{
				unityAsset.name = def.Name;
				OnAssetUpdate(new AssetUpdate()
				{
					Asset = def
				}, null);

				try
				{
					response.Assets = new Asset[] { GenerateAssetPatch(unityAsset, def.Id) };
				}
				catch (Exception e)
				{
					response.FailureMessage = e.Message;
					_app.Logger.LogError(response.FailureMessage);
				}
			}
			else
			{
				if (response.FailureMessage == null)
				{
					response.FailureMessage = $"Not implemented: CreateAsset of new asset type";
				}
				_app.Logger.LogError(response.FailureMessage);
			}

			_app.Protocol.Send(new Message()
			{
				ReplyToId = payload.MessageId,
				Payload = response
			});

			onCompleteCallback?.Invoke();
		}