Страница 1 из 1

Синусоидальный 2D трэк

СообщениеДобавлено: 31 май 2016, 14:42
nilex7
Всем привет,

Создаю 2D дорогу, использую LineRender для визуализации и EdgeCollider2D для физической составляющей дороги.

Все прекрасно работает только дорога прямая.

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

Имею вот какие данные:

Изначальный кусок земли (я ввожу начальную точку и конечную) в котором на "единицу" ширины строиться 5 линий, что бы плавно все выглядело. т.е. на экране дорога будет примерно из 100 отрезков(EdgeCollider2D).
Дальше я получаю кол-во точек и отрезков которые будут всего на данном куске земли. Например 100 отрезков и 101 точка.
После я забиваю координаты X = начальная точка + ширина всей дороги * i / 101 (i - это текущий индекс точки, всего точек 101)
В Y я забиваю просто верхнею координату куска земли.

И получается в итоге прямой кусок земли(линия) и прямой EdgeCollider состоящий из 101 точки и 100 отрезков

Подскажите что присвоить Y что бы получить примерно рандомный синусоид плавный?

Вот кусок рабочего кода.
Vector2[] Points = new Vector2[nodecount]; //инциализируем вектор точек
for(int i=0; i < nodecount; i++){
xpositions [i] = Left + Width * i / edgecount; //массив Х переменных
ypositions [i] = Top; //массив У переменных
MapsLine.SetPosition (i, new Vector3 (xpositions [i], ypositions [i], z)); //устанавливаем позицию для линии
Points.SetValue(new Vector2(xpositions [i], ypositions [i]),i); //устанавливаем позиции точек для коллайдера
MapsLine.GetComponent<EdgeCollider2D> ().points = Points; //Заполняем точки коллайдера

}

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 31 май 2016, 23:44
MANMANA
Поскольку синус - циклическая функция, то вам необходимо менять значения для b и c в формуле y=a+bsin(cx+d) для каждого цикла https://ru.m.wikipedia.org/wiki/Синусоида

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 01 июн 2016, 02:12
Cr0c
Неповторяющийся - это сумма синусов с множителями угла из простого ряда чисел. Можно добавить уникальности добавляя к углу Mathf.Clamp(x, 0, max), где max рандомно генерируется для каждого синуса. Это вообще не сильно простая штука - подобрать множители и коэффициенты сдвига чтобы избежать короткой цикличности (а она будет, синус ведь), но можно её растянуть через нелинейные малоперекрывающиеся сдвиги углов и несоставные (простые) множители. И у каждого следующего синуса должен быть масштаб меньше предыдущего.

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 01 июн 2016, 10:57
nilex7
Cr0c писал(а):Неповторяющийся - это сумма синусов с множителями угла из простого ряда чисел. Можно добавить уникальности добавляя к углу Mathf.Clamp(x, 0, max), где max рандомно генерируется для каждого синуса. Это вообще не сильно простая штука - подобрать множители и коэффициенты сдвига чтобы избежать короткой цикличности (а она будет, синус ведь), но можно её растянуть через нелинейные малоперекрывающиеся сдвиги углов и несоставные (простые) множители. И у каждого следующего синуса должен быть масштаб меньше предыдущего.


Что то не понял :)

У меня вот что получилось

Синтаксис:
Используется csharp
//Заполнение массивов физ.значений и установка позиции линии
                float a = Top;   //Oy
                float b = 0.05f;  //растяжение по Oy
                float c = 0.15f;  //растяжение по Ox
                float d = 0.0f;  //-Ox
                if (Random.Range (0.0f, 100.0f) > 50) {
                        b = 0.05f;
                        b_activ = false;
                } else {
                        b = 0.5f;
                        b_activ = true;
                }
                Vector2[] Points = new Vector2[nodecount];
                for(int i=0; i < nodecount; i++){      
                       
                        if (b_activ == false) {
                                b += 0.01f;
                        }
                        if (b_activ == true) {
                                b -= 0.01f;
                        }

                        xpositions [i] = Left + Width * i / edgecount;
                        ypositions [i] = a + b*Mathf.Sin(c*i + d);

                        if (ypositions [i] > 0.3f) {
                                b_activ = true;
                        }
                        if(ypositions[i] < -0.3f){
                                b_activ = false;
                        }

                        MapsLine.SetPosition (i, new Vector3 (xpositions [i], ypositions [i], z));
                        Points.SetValue(new Vector2(xpositions [i], ypositions [i]),i);
                        MapsLine.GetComponent<EdgeCollider2D> ().points = Points;

                }
 


MapsLine имеет LineRender это к слову.

Получается довольно интересная случайная и плавная синусоида, но резких холмов как хотелось не появляется.
Единственное если начинать менять c также как b то теряется плавность трэка и он превращается в зубчатый местами...
Ковырялся так и не смог изменения по Х нормально сделать. На видео покажу что получилось.

У кого какие идеи есть что бы улучшить модель трэка.

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

https://youtu.be/LuAJUI2YQKA

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 01 июн 2016, 13:51
unk_nown
чтобы сделать это бесконечным, стоит двигать не ГГ а саму карту вокруг него, потому что окружающий мир описан во флоате и у нас есть шанс добраться до его пределов.

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 01 июн 2016, 14:04
Anonymyx
А если карта выйдет за пределы float? :)

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 01 июн 2016, 15:55
unk_nown
так, вероятно, подобное перемещение карты вокруг объекта предполагает генерацию новых ее частей и удаление старых. Разве это не очевидно? :D

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 09:06
nilex7
unk_nown писал(а):так, вероятно, подобное перемещение карты вокруг объекта предполагает генерацию новых ее частей и удаление старых. Разве это не очевидно? :D


Я именно так и написал, создавать три куска земли и по мере движения героя по земле удалять крайнию землю против движения и создавать новую землю в стороне движения, у меня так уже сделано с заднем фоном, на видео видно.
Крутить просто карту а героя оставлять на месте у меня не получиться т.к. я использую 2D физику, у меня гусенечный краб))) он хорошо ездит, обидно его лишать такой радости)))

А еще затык такой интересный, вот это не работает
Синтаксис:
Используется csharp
//Попытка определить слой, но не работает
                MapsLine.GetComponent<LineRenderer> ().sortingLayerName = NameLayer;
                MapsLine.GetComponent<LineRenderer> ().sortingOrder = NumberLayer;

                MapsMesh.GetComponent<MeshRenderer> ().sortingLayerName = NameLayer;
                MapsMesh.GetComponent<MeshRenderer> ().sortingOrder = NumberLayer;


У меня Z у всех объектов 0 кроме камеры, камера -10, но она не причем тут, просто к слову.
Вообщем слой и номер в слое не применяться...нет реакции никакой на это.
А вот на Z реакция есть, но у меня разделения по слоям сделана по имени слоя и по номеру в слое а не по Z

Вот тут Z ставлю и тут видимость меняеться. Но не охото все остальное переделывать со слоев на Z
Синтаксис:
Используется csharp
apsLine.SetPosition (i, new Vector3 (xpositions [i], ypositions [i], z));


В чем ошиибка не пойму никак...

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 11:11
Cr0c
nilex7 писал(а):
unk_nown писал(а):так, вероятно, подобное перемещение карты вокруг объекта предполагает генерацию новых ее частей и удаление старых. Разве это не очевидно? :D


Я именно так и написал, создавать три куска земли и по мере движения героя по земле удалять крайнию землю против движения и создавать новую землю в стороне движения, у меня так уже сделано с заднем фоном, на видео видно.
Крутить просто карту а героя оставлять на месте у меня не получиться т.к. я использую 2D физику, у меня гусенечный краб))) он хорошо ездит, обидно его лишать такой радости)))

Ничего не мешает каждые 100-1000 юнитов от центра перемещать весь мир в начало координат.

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 11:35
nilex7
Cr0c писал(а):
nilex7 писал(а):
unk_nown писал(а):так, вероятно, подобное перемещение карты вокруг объекта предполагает генерацию новых ее частей и удаление старых. Разве это не очевидно? :D


Я именно так и написал, создавать три куска земли и по мере движения героя по земле удалять крайнию землю против движения и создавать новую землю в стороне движения, у меня так уже сделано с заднем фоном, на видео видно.
Крутить просто карту а героя оставлять на месте у меня не получиться т.к. я использую 2D физику, у меня гусенечный краб))) он хорошо ездит, обидно его лишать такой радости)))

Ничего не мешает каждые 100-1000 юнитов от центра перемещать весь мир в начало координат.


физический движок мешает. Читайте руководство http://docs.unity3d.com/ru/current/Manu ... rence.html Юнити.
Перенести картинку это не проблема. Видео мое посмотрите там такое уже есть. Но перемещение физических объектов не делается через transform.position Не стоит идти против рекомендации разрабов Юнити

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 13:59
unk_nown
http://docs.unity3d.com/ru/current/Scri ... Layer.html
я так подозреваю, что те поля, которые вы используете, имеют отношение только к LineRenderer

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 18:03
MANMANA
nilex7 писал(а):Но перемещение физических объектов не делается через transform.position Не стоит идти против рекомендации разрабов Юнити

Не путайте квадратное с зеленым. Крок посоветовал вам телепортировать раз в н-ное количество юнитов всю сцену, а не "перемещать" физические объекты каждый кадр, что и имели ввиду разработчики Юнити :)

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 21:29
nilex7
MANMANA писал(а):
nilex7 писал(а):Но перемещение физических объектов не делается через transform.position Не стоит идти против рекомендации разрабов Юнити

Не путайте квадратное с зеленым. Крок посоветовал вам телепортировать раз в н-ное количество юнитов всю сцену, а не "перемещать" физические объекты каждый кадр, что и имели ввиду разработчики Юнити :)


Читайте лучше комментарии, Крок посоветовал именно перемещать, слово в слово.

Re: Синусоидальный 2D трэк

СообщениеДобавлено: 02 июн 2016, 21:44
Anonymyx
Логика...
Перемещать каждый кадр != перемещать каждый 1000-ый юнит.
Перемещать каждый 1000-ый юнит == телепорт == 1 раз за какое-то время.