Ролевая анимация рандомизированной атаки
Во-первых, я совершенно новичок с аниматором и анимационными системами в единстве.
Чего я пытаюсь достичь (и я пытался с Animator
компонент) - это рандомизированная атака, только когда я удерживаю кнопку мыши нажатой на враге и которая завершает выполнение клипа атаки, который воспроизводится, даже если я пока отпущу кнопку.
Я попытался добавить свои 2 анимации атаки в список и воспроизвести его, что-то вроде
anim.Play(Random.Range(0, list.Count))
... но я не знаю, если проблема в том, что пока я продолжаю нажимать, одна анимация отменяет другую или что.
Поэтому я предпочитаю спрашивать, потому что я, вероятно, делаю вещи неправильно.
Спасибо.
1 ответ
Да, проблема, вероятно, в том, что вы сказали: вам нужно подождать, пока одна анимация не закончилась, прежде чем начинать новую, в противном случае вы будете запускать новую анимацию каждый кадр.
Вы можете использовать Coroutine (также проверьте API), чтобы сделать это.
Конечно, то же самое можно реализовать и в Update
без использования сопрограмм, но в большинстве случаев это становится действительно загроможденным, а иногда и более сложным в обращении. И на самом деле нет никакой потери или выгоды (в отношении производительности) в простом "экспорте" его в сопрограмму.
// Reference those in the Inspector or get them elsewhere
public List<AnimationClip> Clips;
public AnimationClip Idle;
private Animator _anim;
// A flag to make sure you can never start the Coroutine multiple times
private bool _isAnimating;
private void Awake()
{
_anim = GetComponent<Animator>();
}
private void Update()
{
if(Input.GetMouseButtonDown(0)
{
// To make sure there is only one routine running
if(!_isAnimating)
{
StartCoroutine(RandomAnimations());
}
}
// This would immediately interrupt the animations when mouse is not pressed anymore
// uncomment if you prefer this otherwise the Coroutine waits for the last animation to finish
// and returns to Idle state afterwards
//else if(Input.GetMouseButtonUp(0))
//{
// // Interrupts the coroutine
// StopCoroutine (RandomAnimations());
//
// // and returns to Idle state
// _anim.Play(Idle.name);
//
// // Reset flag
// _isAnimating = false;
//}
}
private IEnumerator RandomAnimations()
{
// Set flag to prevent another start of this routine
_isAnimating = true;
// Go on picking clips while mouse stays pressed
while(Input.GetMouseButton(0))
{
// Pick random clip from list
var randClip = Clips[Random.Range(0, Clips.Count)];
// Switch to the random clip
_anim.Play(randClip.name);
// Wait until clip finished before picking next one
yield return new WaitForSeconds(randClip.length);
}
// Even if MouseButton not pressed anymore waits until the last animation finished
// then returns to the Idle state
// If you rather want to interrupt immediately if the button is released
// skip this and uncomment the else part in Update
_anim.Play(Idle.name);
// Reset flag
_isAnimating = false;
}
Обратите внимание, что этот способ рандомизации не обеспечивает такие вещи, как "Не воспроизводить одну и ту же анимацию дважды подряд" или "Воспроизвести все анимации перед повторением одной".
Если вы хотите эту проверку, ответьте на очень похожий вопрос. Там я использовал рандомизированный список для пробежки, чтобы не было двойников