#pragma warning disable 649
using System.Collections.Generic;
using TriLibCore.Extensions;
using TriLibCore.Utils;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace TriLibCore.Samples
{
///
/// Represents a sample that loads a base Model and adds extra Animations from other Models to it.
///
public class LoadExtraAnimationsSample : MonoBehaviour
{
///
/// Returns the path to the base "BuddyBase.fbx" Model.
///
private string BaseModelPath
{
get
{
#if UNITY_EDITOR
return $"{Application.dataPath}/TriLib/TriLibSamples/LoadExtraAnimations/Models/BuddyBase.fbx";
#else
return "Models/BuddyBase.fbx";
#endif
}
}
///
/// Button to instantiate when a new Animation is loaded.
///
[SerializeField]
private Button _playAnimationTemplate;
///
/// The Animation Component from the base Model.
///
private Animation _baseAnimation;
///
/// Gathers the AssetLoaderContext from the loaded Animations.
/// This list is used to process the Animations if the Animations are loaded before the base Model.
///
private readonly IList _loadedAnimations = new List();
///
/// Cached Asset Loader Options instance.
///
private AssetLoaderOptions _assetLoaderOptions;
///
/// Loads the "Models/BuddyBase.fbx" Model, then loads all the extra Animations in the same folder.
///
private void Start()
{
LoadBaseModel();
LoadAnimation("BuddyIdle.fbx");
LoadAnimation("BuddyWalk.fbx");
LoadAnimation("BuddyJump.fbx");
}
///
/// Loads the Animations from the given Model.
///
/// The animated Model filename under the same folder as the base Model.
private void LoadAnimation(string modelFilename)
{
var modelsDirectory = FileUtils.GetFileDirectory(BaseModelPath);
var modelPath = FileUtils.SanitizePath($"{modelsDirectory}/{modelFilename}");
if (_assetLoaderOptions == null)
{
_assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(false, true);
_assetLoaderOptions.ImportMeshes = false;
_assetLoaderOptions.ImportTextures = false;
_assetLoaderOptions.ImportMaterials = false;
}
AssetLoader.LoadModelFromFile(modelPath, OnAnimationModelLoad, null, OnProgress, OnError, gameObject, _assetLoaderOptions);
}
///
/// Gathers all Animations from the loaded Model and adds them to the base Model Animation Component.
///
/// The context used to load the Model.
private void OnAnimationModelLoad(AssetLoaderContext assetLoaderContext)
{
Debug.Log($"Animation loaded: {FileUtils.GetShortFilename(assetLoaderContext.Filename)}");
if (_baseAnimation != null)
{
AddAnimation(assetLoaderContext);
}
else
{
_loadedAnimations.Add(assetLoaderContext);
}
assetLoaderContext.RootGameObject.SetActive(false);
}
///
/// Adds the Animation Clips from the given AssetLoaderContext RootGameObject to the base Model Animations list.
///
/// The AssetLoaderContext containing the loaded Animation component.
private void AddAnimation(AssetLoaderContext loadedAnimationContext)
{
var rootGameObjectAnimation = loadedAnimationContext.RootGameObject.GetComponent();
if (rootGameObjectAnimation != null)
{
var shortFilename = FileUtils.GetShortFilename(loadedAnimationContext.Filename);
var newAnimationClips = rootGameObjectAnimation.GetAllAnimationClips();
foreach (var newAnimationClip in newAnimationClips)
{
var animationName = $"{shortFilename}_{newAnimationClip.name}";
_baseAnimation.AddClip(newAnimationClip, animationName);
var playAnimationButton = Instantiate(_playAnimationTemplate, _playAnimationTemplate.transform.parent);
var playAnimationButtonText = playAnimationButton.GetComponentInChildren();
playAnimationButtonText.text = shortFilename;
playAnimationButton.gameObject.SetActive(true);
playAnimationButton.onClick.AddListener(delegate
{
_baseAnimation.CrossFade(animationName);
});
}
}
Destroy(loadedAnimationContext.RootGameObject);
}
///
/// Loads the Model from BaseModelPath including all Model data.
///
private void LoadBaseModel()
{
if (_assetLoaderOptions == null)
{
_assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(false, true);
}
AssetLoader.LoadModelFromFile(BaseModelPath, OnBaseModelLoad, OnBaseModelMaterialsLoad, OnProgress, OnError, gameObject, _assetLoaderOptions);
}
///
/// Called when any error occurs.
///
/// The contextualized error, containing the original exception and the context passed to the method where the error was thrown.
private void OnError(IContextualizedError obj)
{
Debug.LogError($"An error occurred while loading your Model: {obj.GetInnerException()}");
}
///
/// Called when a Model loading progress changes.
///
/// The context used to load the Model.
/// The loading progress.
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
{
}
///
/// Called when the Base Model (including Textures and Materials) has been fully loaded.
/// This method processes previously loaded Animations from the loaded Animations list.
///
/// The context used to load the Model.
private void OnBaseModelMaterialsLoad(AssetLoaderContext assetLoaderContext)
{
Debug.Log($"Base Model loaded:{FileUtils.GetShortFilename(assetLoaderContext.Filename)}");
_baseAnimation = assetLoaderContext.RootGameObject.GetComponent();
for (var i = _loadedAnimations.Count - 1; i >= 0; i--)
{
AddAnimation(_loadedAnimations[i]);
_loadedAnimations.RemoveAt(i);
}
}
///
/// Called when the Base Model Meshes and hierarchy are loaded.
///
/// The context used to load the Model.
private void OnBaseModelLoad(AssetLoaderContext assetLoaderContext)
{
}
}
}