Всем привет! Я Марк Варламов, Unity-разработчик в Digital Lab и сегодня я расскажу о том, как мы создавали механику рыбной ловли в AR.
Одним из наших проектов стал AR для «Пяти Озер»: игровая механика рыбной ловли в дополненной реальности. Удочку – центральную часть геймплея – нужно было сделать максимально реалистичной.
Целью создания приложения было продвижение бренда «Пять Озер» и новинки Organic filtered в линейке.
Идея
Ее основой стало место происхождения бренда – легендарный край сибирских озер, воду которых прозвали «живой» за особые свойства. Так возникла идея «оживить» реальность и перенести потребителя в мир бренда нажатием одной кнопки.
AR-приложение позволило оригинальным способом рассказать об особенностях нового SKU в линейке «Пять Озер» [удалено модератором, нарушение правил, характеристики продукта].
А еще игра приобрела особую актуальность в условиях новой реальности, когда мы ограничены в выборе мест для путешествий и отдыха.
Механика
После регистрации пользователь выбирает персонажа и отправляется на рыбалку на одно из пяти уникальных озер. По мере роста прогресса ему открываются остальные озера и возможность изменить модель удочки на более продвинутую.
За пойманную рыбу начисляются игровые баллы (разное количество за разные виды рыб). Можно насладиться рыбалкой или посоревноваться с другими игроками за брендированный мерч и главный приз – iPhone 11 Pro.
К участию допускаются игроки старше 18 лет.
Реализация
Приложение разработано под операционные системы iOS 11.0+ и Android 7.0+ на игровом движке Unity. Для дополненной реальности используется платформа ARFoundation, основанная на технологиях Apple ARKit и Google ARCore. Гитхаб.
Сам геймплей был вдохновлен мини-игрой с борьбой на руках из «Ведьмака 2». Нам не хотелось делать монотонное закликивание, поэтому было решено остановиться на плавном смещении зеленой зоны индикатора для увеличения сложности.
Ведьмак 2: Глава I, задание «Борьба на руках: флотзам»
Главная проблема – сгибаемое удилище.
Для реалистичного изгиба генерируем SkinnedMesh из n-костей. Чем дальше кость находится от основания, тем она короче. На каждую кость генерим несколько вершин с разных сторон, с последовательным уменьшением радиуса для придания объема.
Анимация меняет поворот удочки и силу изгиба, поворачивающую каждую из костей.
Поворот костей происходит так: когда рыба натягивает леску, нам надо гнуть удилище в зависимости от силы рывка рыбы в направлении от источника прилагаемой силы (m_forceSource).
Для каждой кости вычисляется вектор направления в сторону рыбы (источника прилагаемой силы) и вектор, вдоль которого направлена кость (вектор up). Затем происходит масштабирование вектора относительно его позиции от основания удилища: чем дальше кость от основания удилища, тем более она гибкая. С помощью вектора, описывающего, куда кость должна развернуться под действием силы, вычисляется кватернион поворота от одного положения до другого.
for (int i = 0; i < bones.Count; i++)
{
Vector3 f = bones[i].parent.worldToLocalMatrix.MultiplyPoint(m_forceSource).normalized;
Vector3 up = bones[i].worldToLocalMatrix.MultiplyVector(bones[i].parent.up).normalized;
Vector3 v = f / ((float)m_steps - i) * m_forceModule;
Vector3 d = (up + v).normalized;
Quaternion rotation = Quaternion.FromToRotation(up, d);
bones[i].localRotation = rotation;
}
Анимация поплавка происходит по сплайнам с помощью плагина Curves and Splines.
Место приземления поплавка находится в дополненной реальности, поэтому необходимо динамически рассчитывать опорные точки. В нашем случае используются 3 точки, из которых формируются 7 позиций:
PoleTip – последняя кость удилища,
DropPoint – условная точка сзади,
PlaceHolder – финальная точка.
PoleTip;
PoleTip + (0, 1, 0);
DropPoint - DropPoint.forward;
DropPoint;
DropPoint + DropPoint.forward * dist(DropPoint, PlaceHolder);
PlaceHolder + (0, -1, 0) * dist(DropPoint, PlaceHolder) / 5;
PlaceHolder.
Для лески с эффектом провисания необходимо создать кривую между двух точек. Мы использовали реализацию отсюда. При обновлении позиции поплавка или удочки задаем начало и конец кривой, где start – последняя кость удилища, а end – финальная точка. В анимации ловли рыбы также меняем параметр slack для изменения уровня натяжения лески.
И отправляемся на реалистичную рыбалку в дополненной реальности!