using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using Random = UnityEngine.Random;
using System.Linq;
//using UnityEditor.Animations;
using System.Reflection;
//using UnityEditor;
public class AnimationLoader : MonoBehaviour
{
public string localDataDirectory = “data/animators/”;
public string localDataDirectoryFileName = “data/animators/init.json”;
public List animationURLs = new List();
private List animatorControllers = new List();
private bool isPlaying = false;
private Animator animator;
private void Start()
{
animator = GetComponent<Animator>();
LoadInitialAnimationUrls();
if (animationURLs.Count > 0)
{
StartCoroutine(LoadAnimations());
}
}
public string GetBaseDir()
{
if (Application.platform == RuntimePlatform.Android)
return Application.persistentDataPath;
return Application.dataPath;
}
private void LoadInitialAnimationUrls()
{
string filePath = Path.Combine(GetBaseDir(), localDataDirectoryFileName);
Debug.LogError($"local {filePath}");
if (File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
animationURLs = JsonUtility.FromJson<UrlList>(json).urls;
}
LoadDefaultInitialAnimationUrls();
}
private void LoadDefaultInitialAnimationUrls()
{
string defaultAnimationsPath = Path.Combine(Application.streamingAssetsPath, "anims");
string[] defaultAnimationFiles = Directory.GetFiles(defaultAnimationsPath, "*.anim");
List<string> defaultUrls = new List<string>();
foreach (string file in defaultAnimationFiles)
{
string url = file;//"file://" +
defaultUrls.Add(url);
}
if (animationURLs == null)
animationURLs = new List<string>();
if(defaultUrls!=null&&defaultUrls.Count>0)
{
animationURLs.AddRange(defaultUrls);
Debug.LogError("添加默认动画成功");
}
}
public void StartAnimation(Animator animator)
{
this.animator = animator;
isPlaying = true;
StartCoroutine(PlayAnimations());
}
public void StartAnimation()
{
isPlaying = true;
StartCoroutine(PlayAnimations());
}
public void StopAnimation()
{
isPlaying = false;
StopCoroutine(PlayAnimations());
}
private IEnumerator LoadAnimations()
{
foreach (string url in animationURLs)
{
string localPath = GetLocalPath(url);
if (File.Exists(localPath))
{
yield return StartCoroutine(LoadAnimationFromLocal(localPath));
}
else
{
yield return StartCoroutine(DownloadAnimation(url, localPath));
}
}
}
private IEnumerator LoadAnimationFromLocal(string localPath)
{
var localLoadRequest = AssetBundle.LoadFromFileAsync(localPath);
yield return localLoadRequest;
if (localLoadRequest.assetBundle != null)
{
var controller = localLoadRequest.assetBundle.LoadAsset<RuntimeAnimatorController>("AnimatorController");
if (controller != null)
{
var clips = localLoadRequest.assetBundle.LoadAllAssets<AnimationClip>();
var item = new AnimatorControllerItem(controller, clips);
animatorControllers.Add(item);
}
localLoadRequest.assetBundle.Unload(false);
}
}
private IEnumerator DownloadAnimation(string url, string localPath)
{
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.LogError("Failed to download animation: " + www.error);
}
else
{
File.WriteAllBytes(localPath, www.downloadHandler.data);
yield return StartCoroutine(LoadAnimationFromLocal(localPath));
}
}
}
private string GetLocalPath(string url)
{
if (url.ToLower().StartsWith("http"))//本地文件,直接返回
{
Uri uri = new Uri(url);
string path = uri.AbsolutePath.TrimStart('/');
return Path.Combine(GetBaseDir(), localDataDirectory, path);
}
return url.Replace("file://", "");
}
private IEnumerator PlayAnimations()
{
while (isPlaying)
{
if (animatorControllers.Count == 0)
{
yield return new WaitForSeconds(3);
continue;
}
AnimatorControllerItem item = animatorControllers[Random.Range(0, animatorControllers.Count)];
var dur = item.GetCurrentClipLength()+6;
item.PlayAnimator(animator);
yield return new WaitForSeconds(dur);
ShuffleAnimatorControllers();
}
}
private void ShuffleAnimatorControllers()
{
for (int i = 0; i < animatorControllers.Count; i++)
{
AnimatorControllerItem temp = animatorControllers[i];
int randomIndex = Random.Range(i, animatorControllers.Count);
animatorControllers[i] = animatorControllers[randomIndex];
animatorControllers[randomIndex] = temp;
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
StartAnimation();
}
else if (Input.GetKeyDown(KeyCode.T))
{
StopAnimation();
}
}
}
[System.Serializable]
public class UrlList
{
public List urls;
}
public class AnimatorControllerItem
{
public RuntimeAnimatorController controller;
public AnimationClip[] Clips { get; }
public string[] ClipNames;
private string clipName;
public AnimatorControllerItem(RuntimeAnimatorController controller)
{
this.controller = controller;
}
public AnimatorControllerItem(RuntimeAnimatorController controller, AnimationClip[] clips) : this(controller)
{
Clips = clips;
//GetStateNames(controller);
ClipNames = GetClipNames();// clips.Select(p=>p.name).ToArray();
if (ClipNames == null|| ClipNames.Length==0)
{
ClipNames = new string[] { "Idle", "Talking1", "Idle", "Talking1", "Idle", "Talking1", "Idle", "Walking", "Idle" };//Talking2 Talking3
}
string josnString = String.Join(" ", ClipNames);
Debug.LogError(clips.Length + " " + josnString);
// FixAnimationClipSettings(controller);
}
private string[] GetClipNames()
{
return statesNames.ToArray();
}
public void PlayAnimator(Animator animator)
{
//GetCurrentClipLength 执行這个函数后执行
animator.runtimeAnimatorController = controller;
//animator.CrossFade("Walking",0.2f,0,0);
Debug.LogError("playing "+ clipName);
//animator.Play(clipName); //Walking Idle
animator.CrossFade(clipName, 0.2f, 0, 0);
}
public float GetCurrentClipLength()
{
if (controller != null&& ClipNames!=null&& ClipNames.Count()>0)
{
clipName = ClipNames[Random.Range(0, ClipNames.Length)];
var clips = Clips.Where(p => p.name == clipName).FirstOrDefault();
if (clips != null)
{
return clips.length;
}
}
return 0;
}
public List<string> statesNames = new List<string>();
//private string[] GetClipNames(RuntimeAnimatorController controller)
//{
// AnimatorOverrideController overrideController = controller as AnimatorOverrideController;
// Debug.LogError($"{overrideController}");
// List<string> clipNames = new List<string>();
// foreach (AnimationClip clip in controller.animationClips)
// {
// // 如果有修改后的别名,则使用别名,否则使用原始名称
// string clipName = clip.name;
// if (overrideController != null)
// {
// clipName = overrideController[clip].name;
// }
// clipNames.Add(clipName);
// }
// return clipNames.ToArray();
//}
}