using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
public static class IListExtensions
{
public static void Shuffle<T>(this IList<T> ts)
{
var count = ts.Count;
var last = count - 1;
for (var i = 0; i < last; ++i)
{
var r = UnityEngine.Random.Range(i, count);
var tmp = ts[i];
ts[i] = ts[r];
ts[r] = tmp;
}
}
}
public class PlayAnimations : MonoBehaviour
{
public Animator animator;
private AnimationClip[] clips;
private List<AnimationClip> clipsList = new List<AnimationClip>();
private string[] names;
private void Awake()
{
clips = animator.runtimeAnimatorController.animationClips;
for (int i = 0; i < clips.Length; i++)
{
if (clips[i].name.Contains("mixamo"))
{
clipsList.Add(clips[i]);
}
}
}
public void Init()
{
if (clipsList.Count > 0)
{
StartCoroutine(PlayRandomly());
}
}
private IEnumerator PlayRandomly()
{
while (true)
{
clipsList.Shuffle();
foreach (var randClip in clipsList)
{
animator.Play(randClip.name);
yield return new WaitForSeconds(randClip.length);
}
}
}
}
异常消息:
InvalidOperationException:集合已修改;枚举操作可能无法执行。
在线:
foreach (var randClip in clipsList)
我正在尝试播放包含maximo
的所有动画剪辑。
此脚本中我唯一调用Init方法并开始播放动画的播放器:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimatorController : MonoBehaviour
{
public Animator[] animators;
public Transform target;
public float speed = 1f;
public float rotationSpeed;
public bool slowDown = false;
public PlayAnimations playanimation;
private bool endRot = false;
private Vector3 center;
// Use this for initialization
void Start()
{
center = target.GetComponent<Renderer>().bounds.center;
for (int i = 0; i < animators.Length; i++)
{
animators[i].SetFloat("Walking Speed", speed);
}
}
// Update is called once per frame
void Update()
{
float distanceFromTarget = Vector3.Distance(animators[2].transform.position, target.position);
for(int i = 0; i < animators.Length; i++)
{
animators[2].transform.position = Vector3.MoveTowards(animators[2].transform.position, center, 0);
}
if (slowDown)
{
if (distanceFromTarget < 10)
{
float speed = (distanceFromTarget / 10) / 1;
for (int i = 0; i < animators.Length; i++)
{
animators[i].SetFloat("Walking Speed", speed);
}
}
}
if (distanceFromTarget < 5f)
{
for (int i = 0; i < animators.Length; i++)
{
//animators[i].SetFloat("Walking Speed", 0);
animators[i].SetBool("Idle", true);
playanimation.Init();
}
if (!endRot)
{
Quaternion goalRotation = Quaternion.Euler(0f, 0f, 0f);
float angleToGoal = Quaternion.Angle(
goalRotation,
animators[0].transform.localRotation);
float angleThisFrame = Mathf.Min(angleToGoal, rotationSpeed * Time.deltaTime);
// use axis of Vector3.down to keep angles positive for ease of use
animators[0].transform.Rotate(Vector3.up, angleThisFrame);
animators[1].transform.Rotate(Vector3.down, angleThisFrame);
// We end if we rotated the remaining amount.
endRot = (angleThisFrame == angleToGoal);
}
{
animators[0].SetBool("Rifle Aiming Idle", true);
animators[1].SetBool("Rifle Aiming Idle", true);
}
}
}
}
在更新内的行上:
playanimation.Init();
答案 0 :(得分:1)
您要在Update
的{{1}}中启动协程
AnimatorController
始终位于同一组件if (distanceFromTarget < 5f)
{
for (int i = 0; i < animators.Length; i++)
{
//animators[i].SetFloat("Walking Speed", 0);
animators[i].SetBool("Idle", true);
playanimation.Init();
}
//...
上。另外,它被放置在PlayAnimations playanimation
中,因此可能会被更频繁地调用。
这使您可以使用多个并发的协程来操纵相同的值Update
:
当前一个例程可能已经在执行clipsList
循环,而第二个例程则更改了
foreach
的内容
clipsList
这不是“允许的”->查看您的例外情况
确保只运行一次例程:
clipsList.Shuffle();
或/和通常优化private bool wasInitialized;
public void Init()
{
// Only start the coroutine if not initialized yet
if (!wasInitialized && clipsList.Count > 0)
{
wasInitialized = true;
StartCoroutine(PlayRandomly());
}
}
来完全避免那些多余的呼叫。