Суббота, 23 Ноября 2024, 11:03

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [358]
Статьи об общих понятиях связанных с созданием игр.
Программирование [83]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [147]
Статьи о программах для создания игр, уроки и описания.
Софт [43]
Различные программы, в том числе в помощь игроделам.
2D-графика [14]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [17]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [5]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [167]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [132]
Статьи, которые не вошли в определённые разделы.
Наш опрос
Вы создаете собственные сайты?
Всего ответов: 1929
Главная » Статьи » Создание игр

Движение объектов по определенной траектории с помощью математики
Предисловие


В этой статье я планирую рассказать вам, как математика и тригонометрические функции помогут вам сделать движение в вашей игре плавным и красивым. Я расскажу здесь про то, как заставить объект плавно поворачиваться в сторону цели с помощью Vector3.Lerp();, как заставить объект двигаться по траектории знака бесконечности и покажу еще много интересных примеров использования математики в подобных целях!
Для демонстрации я буду использовать известный движок Unity, подкрепленный языком программирования C#, но поскольку эта статья больше про математику, а не про пользование конкретным языком/движком, вам не составит труда понять основную мысль и перенести все полученные знания в другую среду разработки.

Краткий экскурс в тригонометрию


Большую роль в этой статье будет играть тригонометрия, поэтому давайте быстренько пройдемся по основам, которые помогут вам понять, как работает все, что мы будем делать дальше.

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

см. единичная окружность



Теперь, после того, как мы посмотрели на единичную окружность, я предлагаю вам разобраться с синусом (его одного нам пока будет достаточно)

Если кратко и только по делу, синус - это тригонометрическая функция, которая принимает значение от -1 до 1 на единичной окружности. Давайте посмотрим, как постоянно увеличивающаяся градусная мера среднего угла единичной окружности образует синусоиду



Двигаем объект по разным траекториям


Сейчас, я думаю, многие поняли, что мы будем делать. Мы заставим объект двигаться по синусоиде! Для этого давайте напишем простой код на C#

Код

public GameObject obj; //Объект, который будет двигаться по синусоиде
void Update()
{
  obj.transform.position = new Vector2(0, Mathf.Sin(Time.time)); //Заставляем наш объект двигаться по синусоиде по оси Y
}


//Если в среде разработки, которую вы используйте у вас нет доступа ко времени работы программы, то вы можете просто
//создать переменную time и прибавлять к ней единицу каждый кадр. Работает это точно так же как в случае с Time.time в Unity.

Хорошо, теперь посмотрим, что у нас получилось:



Класс! Посмотрите как плавно перемещается наш объект, и это делается всего одной строчкой кода! Сразу в голове начинают появляться способы применения. Самый очевидный, как я думаю - анимация парящих объектов вроде вертолетов или летающих островов. Теперь давайте разберемся с тем, как менять характеристики нашей синусоиды. Давайте уменьшим амплитуду (высоту волны) и уменьшим длину волны (тем самым мы прибавим скорость)

Код

public GameObject obj; //Объект, который будет двигаться по синусоиде
void Update()
{
  obj.transform.position = new Vector2(0, A * Mathf.Sin(Time.time * L)); //Заставляем наш объект двигаться по синусоиде по оси Y
}


Вместо A подставляем значение амплитуды. В данном случае это 0.5f
Ну а вместо L подставляем скорость. Я подставил 4.

Смотрим результат:



Отлично, все работает так, как надо :) Теперь давайте будем двигать объект не только по оси Y но и по X. Только теперь нам пригодится косинус.
Напишем следующий код:

Код

public GameObject obj; //Объект, который будет двигаться по синусоиде
void Update()
{
  obj.transform.position = new Vector2(0.5f * Mathf.Cos(Time.time * 4), 0.5f * Mathf.Sin(Time.time * 4)); //Заставляем наш объект двигаться по синусоиде по оси X и Y
}


результат:

Движение по окружности!



Ну а самое интересное я оставил напоследок. Следующий код заставит объект двигаться по траектории знака бесконечности.
Код

  public float speed = 4;
  public float scaleX = 1f;
  public float scaleY = 1f;
  float cornerAngle = 0;
  void Update()
  {
  cornerAngle += Time.deltaTime * speed;
  transform.position = new Vector3(Mathf.Cos(cornerAngle) * scaleX, Mathf.Sin(cornerAngle) * Mathf.Cos(cornerAngle) * scaleY, 0);
  }




Если вы хотите углубиться в то, как это работает, вот вам ссылка на википедию: Лемниската Бернулли

Lerp и Slerp


С тригонометрией на сегодня покончено. Поговорим о такой штуке как Lerp.
Линейная интерполяция (Linear interpolation, Lerp — очень удобная функция при разработке игр, которая интерполирует значение в диапазоне от и до на основе параметра time, где time обычно находится в диапазоне от 0 до 1. Например, это можно использовать для резкого перемещения (прыжка) из одной точки в другую, либо для быстрого поворота объекта в сторону цели.
Давайте напишем код, который будет перемещать объект из одной точки в другую с помощью Lerp.

Код

  public float time;
  public Transform target;
  void Update()
  {
  transform.position = Vector3.Lerp(transform.position, target.position, time);
  }


Результат:



Тоже самое можно сделать и для поворота объекта к цели.

Код

  public float time;
  public Transform target;
  void Update()
  {
  Vector3 dir = target.position - transform.position;
  Quaternion rotation = Quaternion.LookRotation(dir);
  transform.rotation = Quaternion.Lerp(transform.rotation, rotation, time * Time.deltaTime);
  }


гифки не будет, так как я устал их делать

UPD: Если в вашей среде разработки отсутствует функция lerp, вот код, который находится внутри Vector3.Lerp(); в Unity

Код

public static Vector3 Lerp(Vector3 a, Vector3 b, float t)
{
  t = Mathf.Clamp01(t);
  return new Vector3(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}


Кроме Lerp есть еще и Slerp. По идеи, это тоже самое, но только двигаться наш объект будет не по прямой, а по окружности. Напишем код, идентичный предыдущему, только заменим Lerp на Slerp

Код

  public float time;
  public Transform target;
  void Update()
  {
  transform.position = Vector3.Slerp(transform.position, target.position, time);
  }


Вот какой интересный результат у нас получился:



Пожалуй, на этом мы и остановимся. Надеюсь, что после прочтения этой статьи вы смогли подчеркнуть для себя что-нибудь интересное, что будет делать ваши игры лучше, а сейчас на этом все. Благодарю вас за время, уделенное этой статье и прощаюсь. Пока! :D

Источник: КЛИК»
Категория: Создание игр | Добавил: Core (19 Июля 2022) | Автор: Андрей (JustCore)
Просмотров: 4208 | Комментарии: 5 | Рейтинг: 5.0/11 |
Теги: Unity, тригонометрия, C#, поворот объектов, математика, движение объектов, движение
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «Движение объектов по определенной траектории с помощью математики», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 5
+3-
2 CaptainHunt   (24 Июля 2022 19:04) [Материал]
CaptainHuntХорошая статья. Есть некоторые интересные моменты с тригонометрией, в которых хочу разобраться. Автору респект!

+1-
3 Core   (24 Июля 2022 19:39) [Материал]
CoreСпасибо. Рад, что статья оказалась полезной

+1-
1 TLT   (22 Июля 2022 23:55) [Материал]
TLTКак хорошо, когда в API всё прописано и можно так скриптовать... Раньше всё было сложнее.

+1-
4 Core   (24 Июля 2022 19:41) [Материал]
CoreСогласен. Технологии очень быстро шагают вперед. Недавно посмотрел, как компьютер рассчитывает тригонометрические функции на низком уровне. Ужас какой-то =)

+1-
5 TLT   (25 Июля 2022 19:53) [Материал]
TLTДля синусов обычно составляли таблицу и по ней программировали траектории. Я сейчас так для ретро-систем делаю иногда...

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • Bitsy
  • Flax
  • Intersect Engine
  • Aether3D
  • Playir
  • URQ
  • Genesis 2D
  • FIFE
  • Maratis Engine
  • BlitzMax
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    Все права сохранены. GcUp.ru © 2008-2024 Рейтинг