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