Как использовать класс AnimationCurve для анимации игровых объектов

Меня поражает, как Unity предоставляет массу различных инструментов для работы. Сегодня я предлагаю новый быстрый совет, который вы можете использовать в своих играх, Curve Animator.

Этот простой инструмент дает вам возможность программно анимировать игровые объекты.

Это сбывшаяся мечта для такого программиста, как я, который любит программировать анимацию с помощью кода... Нет, не совсем, но мне это нравится.
Идея этого класса проста: в простой скрипт MonoBehaviour вы добавляете Элемент Curve Animator, а визуальная кривая позволяет настроить «анимацию».

Примеров бесчисленное множество, вот некоторые из них:

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

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

Этот пример звонит в колокол? Вы знаете эту игру, в которой объекты появляются далеко от вас, и они приближаются к вам, и ваша цель — нарезать их?

Ну, вы можете использовать этот простой пример, чтобы сделать это.

Шаг 1. Создайте генератор моноповедения для создания объектов

Назначьте этот новый сценарий игровому объекту. Скопируйте и вставьте следующий код в скрипт Spawner:

public class Spawner : MonoBehaviour
{  
   [Header("Spawner Settings")]
   // Object to be spawned
   [SerializeField] private AnimatedCurveObject objectToSpawnPrefab;

   [SerializeField] private float spawnFrecuency = 0.5f;
   [SerializeField] private int totalObjectsToSpawn = 20;

   private int numberObjectsSpawned = 0;
   void Start()
   {
        numberObjectsSpawned = 0;
       // Coroutine to spawn objects 
        StartCoroutine(SpawnAnimatedObjects());
    }
    private IEnumerator SpawnAnimatedObjects()
    {
        while (numberObjectsSpawned < totalObjectsToSpawn)
        {
           yield return new WaitForSeconds(spawnFrecuency);

           AnimatedCurveObject spawned =  
                     Instantiate(objectToSpawnPrefab);
           if (spawned != null)
           {
              spawned.transform.parent = transform;
           }
           numberObjectsSpawned += 1;
        }
    }
}

Этот скрипт использует сопрограмму для создания 20 объектов каждые 0,5 секунды в месте создания.

Вы можете настроить количество создаваемых объектов и частоту в редакторе.

Шаг 2. Создайте игровой объект для создания

Этот игровой объект содержит кривую анимации движения. Предыдущий игровой объект порождает объекты этого типа.

Шаг 3. Создайте скрипт для создания объекта

Скрипт перемещает объект по оси Z с постоянной скоростью. Сейчас он не использует класс AnimationCurve, но мы будем использовать его для чего-то более интересного.

public class AnimatedCurveObject : MonoBehaviour
{
    [SerializeField] AnimationCurve animationCurve;
    [SerializeField] private float speed = 100.0f; 

    void Start()
    {
        // Auto destroy object after 5 seconds
        Destroy(gameObject, 15.0f);
    }

    void Update()
    {
       // Move the object in Z position with constant speed
       Vector3 currentPosition = transform.position;
       currentPosition.z += speed * Time.deltaTime;
       transform.position = currentPosition;

    }
 }

Шаг 4. Использование AnimationCurve для обновления положения Y объекта

Сейчас это скучно, сферы двигаются по оси Z линейно, и никакого азарта в этом нет. Добавим крутое движение.

Теперь нам пригодится AnimationCurve; мы можем использовать их для регулировки положения Y с течением времени в разных точках, посмотрите следующее видео, чтобы увидеть пример:

В этом примере положение Y каждой сферы перемещается с захватывающим эффектом; Я уверен, что это достижимо с некоторыми математическими функциями, но AnimationCurve дает больше гибкости.

Концепция проста; вы настраиваете кривую в редакторе как хотите, единственное правило, которому нужно следовать, это то, что у вас есть только 2 оси, одна из которых контролирует время, а другая — значение за это время.

Вы можете использовать это значение и переводить все, что хотите. В этом случае я применяю значение с течением времени для позиции Y:

Выглядит безумно, но очень мощно. Я решил сойти с ума и выставил следующие значения:

Time = 0.0  Value = 4.5
Time = 0.7  Value = 5.3
Time = 1.4  Value = -0.5
Time = 2.5  Value = 0.25

Чтобы взять каждое ключевое значение и промежуточные значения, нам нужно использовать следующую функцию:

public float Evaluate(float time);

Метод Evaluate дает нам соответствующее значение, в данном случае положение Y для сферы во времени.

Чтобы завершить сценарий AnimatedCurveObject, нам нужно число с плавающей запятой для передачи параметра времени и использования результата в текущей позиции:

// Declare the float to use with the animation curve
private float curveDeltaTime = 0.0f;
// Complete the update code 
void Update()
{
   // Get the current position of the sphere
   Vector3 currentPosition = transform.position;
   currentPosition.z += speed * Time.deltaTime;
   // Call evaluate on that time   
   curveDeltaTime+= Time.deltaTime;   
   currentPosition.y = animationCurve.Evaluate(curveDeltaTime);   
   // Update the current position of the sphere
   transform.position = currentPosition;
}

И вуаля! У вас есть захватывающая анимация для сферы.
Вы можете растянуть время, изменить ключевые кадры и использовать значения для другой цели…. Возможности безграничны.

Спасибо, что прочитали этот блог разработчиков.
Надеюсь, вам понравилось читать это так же, как и мне, когда я его писал.

Вы можете найти меня в: