Как поставить анимацию на паузу unity
Перейти к содержимому

Как поставить анимацию на паузу unity

  • автор:

Сделать паузу с анимацией

Как сделать паузу на 5 секунд, чтоб открывалось окно с анимацией (она как раз таки длится 5 секунд), после чего окно закрывалось и пауза снималась?

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Logist : MonoBehaviour < public Syn[] BallGenerationsPrefabs; public GameObject pause; private void OnEnable() =>Syn.BallsCollided += OnBallsHit; private void OnDisable() => Syn.BallsCollided -= OnBallsHit; private void OnBallsHit(Syn ballA, Syn ballB) < if (ballA.GenerationId == ballB.GenerationId) < Vector3 middlePosAB = Vector3.Lerp(ballA.transform.position, ballB.transform.position, 0.5f); int nextGenerationId = ballA.GenerationId + 1; Instantiate(BallGenerationsPrefabs[nextGenerationId], middlePosAB, Quaternion.identity); ScoreScript.gems += nextGenerationId; if (nextGenerationId == 9) < DiamondScript.gems += 1; //Здесь нужно чтоб игра встала на 5 секунд с анимацией и GameObject(pause) включился. На нем и висит анимация. //пока я здесь прописал просто паузу и включение объекта. pause.SetActive(true); Time.timeScale = 0; >ballA.DestroySelf(); ballB.DestroySelf(); > > >

Может это сделать отдельным скриптом и перенаправлять с этого туда?
Или как-то еще, подскажите пожалуйста

#1
15:50, 12 июля 2022

Странно, откуда берутся люди, которые знают про делегаты, но не знают про корутины или апдейты =\

#2
15:56, 12 июля 2022

Неуместно умничаешь. Т.к. есть форумы, а я этим занимаюсь меньше месяца.

  • A_Kuzmin
  • Пользователь

#3
17:13, 12 июля 2022

QuickQuest
> Как сделать паузу на 5 секунд, чтоб открывалось окно с анимацией (она как раз
> таки длится 5 секунд), после чего окно закрывалось и пауза снималась?

Привязать то что должно двигаться и обновляться во время паузы к параметру Time.unscaledTime.
запускать корутину, которая через unscaledtime отсчитывает 5 секунд и после этого удаляет всплывающее окно.

если в паузе проигрывается например персонажная анимация, то в аниматоре можно выставить для update mode опцию unscaled time.

#4
17:36, 12 июля 2022

A_Kuzmin
Спасибо БОЛЬШОЕ!

Как привязать анимацию к открытию/закрытию меню паузы на Unity?

введите сюда описание изображения

Я создал аниматор с двумя анимациями для открытия и закрытия меню паузы в игре следующим образом: Но когда я запускаю это меню, ни одна из анимаций не срабатывает. Я новичок в Unity UI, но предполагаю, что нужно вставить вызов из аниматора в скрипт. Я пробовал несколько способов, но постоянно выдавало разные ошибки. Мог бы кто-нибудь помочь встроить вызов анимаций из скрипта правильным образом? Заранее спасибо за помощь! Вот скрипт:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Pause_menu : MonoBehaviour < public static bool GameIsPaused = false; public GameObject pauseMenuUI; void Update() < if (Input.GetKeyDown(KeyCode.Escape)) < if (GameIsPaused) Resume(); else Pause(); >> public void Resume() < pauseMenuUI.SetActive(false); Time.timeScale = 1f; GameIsPaused = false; >void Pause() < pauseMenuUI.SetActive(true); Time.timeScale = 0f; GameIsPaused = true; >> 

Отслеживать

задан 17 мая 2023 в 14:18

30 6 6 бронзовых знаков

Русские Блоги

Чтобы сделать прямую и обратную анимацию в аниматоре, вы действительно можете сделать две анимации и сделать анимации перехода между ними, но теперь мы говорим об одной анимации, которая останавливается, вперед и назад.

Прежде всего,Используется в старой версии Аниматора с анимацией: скорость = 1 (вперед), скорость = -1 (назад), скорость = 0 (стоп).

Примечание: теперь настройка скорости недействительна

Посмотрите на код:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class AnimController : MonoBehaviour < public Animator ani; private void Start() < ani.speed = 0; >/// /// Скорость прямой трансляции 1 /// public void OnClickForward() < //ani.speed = 2; Скорость движения вперед равна 2 ani.speed = 1; >/// /// тайм-аут /// public void OnClickPause() < ani.speed = 0; >/// /// Скорость перемотки 1 /// public void OnClickBack() < ani.speed = -1; >> 

затем,Посмотрите на текущую практику:

Добавьте переменную с плавающей точкой к параметрам аниматора, а затем назначьте эту переменную анимационному клипу, который необходимо воспроизвести.

Посмотрите на код:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class AnimController : MonoBehaviour < public Animator ani; private void Start() < ani.SetFloat("speed", 0); >/// /// Скорость прямой трансляции 1 /// public void OnClickForward() < ani.SetFloat("speed", 1.0f); >/// /// тайм-аут /// public void OnClickPause() < ani.SetFloat("speed", 0); >/// /// Скорость перемотки 1 /// public void OnClickBack() < // Скорость перемотки 1 //ani.SetFloat("speed ", -5.0f); Скорость обратного воспроизведения 5 ani.SetFloat("speed", -1.0f); >> 

Создание игры на ваших глазах — часть 7: 2D-анимации в Unity («как во флэше»)

В этой статье поговорим о 2D анимациях в Unity. Я расскажу о своем опыте работы с родными анимациями в юнити, о том, насколько тайм-лайны похожи на флэшевские, об управлении анимациями, event’ах, вложенности, и о том, как художник справляется с анимированием.

Для начала, немного теории.

В Unity есть две сущности:

1. Анимация (то, что отображается в окно «Animation»)
2. Mechanim дерево анимаций (то, что отображается в окне «Animator»).

Ниже я немного расскажу, что это такое и как нам может приходиться (или не пригодиться).

Animation

Итак, анимация. По сути — это таймлайн с ключевыми кадрами. Здесь вы можете двигать, поворачивать, масштабировать ваши объекты. Естественно, можно рисовать кривые и пользоваться разными изингами. И даже управлять любыми (в т.ч. самописными) их свойствами. То есть вполне можно написать компонент с float паблик-значением «яркость» и эту самую «яркость» анимировать наравне с x, y, z штатными средствами. Спрайты поддерживают покадровую анимацию.

Кстати, несмотря на то, что у каждой анимации есть FPS (поле «sample»), сами анимации к FPS не привязаны. Они привязаны ко времени. Т.е. если вы делаете анимацию с 5 FPS, где у вас объект двигается из точки А в точку Б с помощью задания двух ключевых кадров в начале и в конце, то в игре этот объект не будет двигаться ступеньками с 5 FPS. Анимация рассчитывается каждый кадр игры, а FPS внутри анимации сделан лишь для вашего удобства, чтобы вам не частить кадры.

Animator

Это — большая и сложная система, которая непосредственно управляет анимациями. То есть анимация — это просто файл (ресурс) с настройками ключевых кадров и сама по себе ничего не умеет. Вот именно компонент «Animator» — это то, что умеет играть эти анимации.

Кроме того, вы можете создавать дерево этих анимаций с морфингом между ними. Т.е. если у вас есть персонаж, анимированный перекладками (когда каждая часть тела — отдельный спрайтик, который вы вращаете/двигаете), то вполне можно сделать анимацию ног отдельно, анимацию рук — отдельно. А потом (с помощью мышки) настроить условие, что от скорости движения вашего объекта, mechanim аниматор будет включать либо анимацю ног «ходьба», либо «бег». А стрелять ваш персонаж будет отдельной анимацией, которая никак не связана со скоростью переставления ног.

В самом же просто случае, ваш аниматор будет выглядеть так:

то есть содержать одну-единственную анимацию и никаких связей/переходов.

Начинаем шаманить.

Пока все понятно. Но давайте подумаем, как сделать что-то чуть более сложное?

Мой конкретный случай — у нас есть сугроб снега, в котором сидит заяц. Сугроб сам по себе шевелится:

Далее, мы хотим сделать такую анимацию:

1. сугроб, шевелясь, двигается влево
2. из сугроба выглядывает заяц (анимация пульсации останавливается):

3. сугроб двигается вправо

В принципе, ничего сложного. Анимируем пульсацию сугроба внутри объекта, внешним аниматором двигаем его влево, потом скрываем, вместо него показываем покадровую анимацию выглядывающего зайца, потом обратно. И все это на одном таймлайне (кроме «внутренней» анимации сугроба).

Но такой вариант мне не нравится его жесткостью. В первую очередь я считаю неправильным, что в таком варианте покадровая анимация вылезающего кролика оказывается на том же таймлайне, что и движение сугроба. Это значит, что если мы захотим сделать вариацию этой анимации, где сугроб будет двигаться по другой траектории, мы должны будем заново анимировать вылезание зайца. А если мы потом это самое вылезание захотим поправить, то нам придется делать это во всех анимациях, где оно используется.

Хотелось бы большей гибкости.

Есть другой вариант. Мы анимируем выглядывание зайца в отдельном объекте (так же, как мы сделали это с шевелением сугроба), а в основном тайм-лайне просто включаем этот объект (active) в нужный момент и анимация начинается.

Это уже гораздо лучше, но все равно не идеально. Ведь в таком случае мы должны в нашем основном таймлайне знать, какой длины анимация этого вылезания. Чтобы включить и отключить ее в нужный момент. А что если мы опять-таки поменяем эту анимацию и заяц будет дольше смотреть по сторонам? Да и вообще, в каких-то более сложных случаях нам будет еще сложнее уместить все в один таймлайн.

Идеально было бы иметь возможность поставить основной таймлайн на паузу, начать проигрывание вложенной анимации и снять его с паузы уже по окончании этой вложенной анимации (или по какому-то событию в ней).

То есть сделать так:

1. движение влево
2. прячем пульсирующий сугроб, показываем анимацию вылезания кролика, встаем на паузу
3. прячем анимацию вылезание кролика, показываем шевелящийся сугроб, двигаемся вправо

Что нам для этого понадобится? Unity позволяет добавлять на анимацию вызов кастомных юзер event’ов. Это именно то, что нам нужно! Осталось только правильно все написать.

Первое, что нам понадобится, это написать простой компонент (в нашем случае он называется GJAnim ) и повесить его на тот же объект, на котором висит наш аниматор. Именно методы этого компонента мы сможем вызывать событиями с таймлайна.

Напишем метод для постановки на паузу. Кстати, в юнити нет такой прямой возможности. Для того, чтобы поставить на паузу анимацию, обычно применяется немного грязный хак с выставлением ее скорости в 0. Он в целом работает, правда, странности есть (об этом — в последней части статьи).

public void Pause() < _animator.speed = 0; >protected void Resume()

Где _animator — это переменная, в которой мы закешировали компонент » Animator «:

_animator = GetComponent(); 

Если вы обратили внимание на скрин выше, над ключевым кадром, который я пометил цифрой «2» стоит небольшая вертикальная черта. Именно за ней скрывается вызов события (метода) «Pause»:

Стоит отметить, что в такие события можно даже передавать параметр. Поддерживаются string, float и объект из библиотеки (не со сцены).

Ок, на паузу мы поставили. Теперь задача — снять с паузы. Очевидно, это должна делать вложенная анимация. То есть доиграла анимация вылезающего кролика до конца, и прокинула наверх события «пошли дальше».

 public void ResumeParent() < Transform pr = transform; while (true) < pr = pr.parent; if (pr == null) < Debug.LogWarning("No GJAnim found in parents!"); return; >GJAnim a = pr.gameObject.GetComponent(); if (a != null) < a.Resume(); return; >> > 

Этот метод ищет среди родителей компонент » GJAnim » и снимает его с паузы. Соответственно, ставим это событие на окончание анимации нашего кролика:

Profit!

Собственно, все. Мы написали простой компонент, который позволяет управлять вложенными/родительскими анимациями и обладает достаточной гибкостью. Возможно, понадобится еще метод типа ResumeByName(string) , который бы снимал с паузы конкретную анимацию, а не первую родительскую.

Кроме того, все делается в пределах юнитевского UI и достаточно прозрачно для любого аниматора. Наш художник через час попадания ему в руки этого инструмента, уже во всю анимировал.

О багах Unity и сумасшествии.

Однако, не все так гладко. В какой-то момент, создав анимацию, мы увидели, что она ведет себя неправильно.

У нас была родительская (главная) анимация, которая показывала один объект (скрывала все остальные), вставала на паузу, в это время в этом объекте начинала проигрываться своя (вложенная) анимация, которая снимала родителя с паузы по окончании. Далее — показывался следующий объект и т.п.

Так вот, мы заметили, что кадры иногда проскакивают.

Долго-долго дебажили, много писали в лог… и вот что выяснили:

По видимому, в юнити есть какой-то стэк кадров/событий анимаций. И когда компьютер (редактор unity) подтормаживает, он может положить в этот стек сразу два кадра, чтобы в следующую итерацию выполнить их оба.

Это влечет за собой чуть ли не полностью неисправимый фейл. Мы ловили ситуацию, когда аниматор выполнял все действия с кадром и вставал на паузу (это ок), а потом в этот же кадр выполнял еще и следующий кадр. То есть за один кадр рассчитывал сразу два кадра анимации. И то, что в 1-м кадре было событие, ставящее скорость анимации в 0, не мешало ему рассчитать еще и следующий кадр, который, по видимому, уже лежал в стеке.

И если в анимации с кроликом этого бы никто не заметил (кролик бы вылез на пиксель не на том месте), то когда вы каждый кадр что-то прячете и показываете, тут может быть фейл.

На данный момент проблема выглядит неисправимой. Как мы справились? Поставили FPS таких анимаций в 20. Видимо, на таком FPS’е случая, когда юнити хочет просчитать два кадра за одну итерацию — не случается.

Но все равно, ситуация не очень. Получается, что при каких-то фризах на компьютере (или на очень тормозных), все равно игрок сможет словить сбой анимаций.

Что с этим делать — не ясно.

  1. Идея, вижен, выбор сеттинга, платформы, модели распространения и т.п
  2. Шейдеры для стилизации картинки под ЭЛТ/LCD
  3. Прикручиваем скриптовый язык к Unity (UniLua)
  4. Шейдер для fade in по палитре (а-ля NES)
  5. Промежуточный итог (прототип)
  6. Поговорим о пиаре инди игр
  7. 2D-анимации в Unity («как во флэше»)
  8. Визуальное скриптование кат-сцен в Unity (uScript)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *