Очень интересная реализация интересной механики. Также хотел сказать спасибо за бесплатный курс по разработке браузерных игр на Unity (На яндексе), тоже очень интересно и полезно!
Прекрасно! Я уже пробовал подобное написать, но потом уперся в то, что на линии может быть несколько пересечений, полез исправлять, по дороге пооптимизировал производительность, и все вообще перестало работать. А потом на работе начался завал и я забросил идею реанимировать алгоритм :( Я вот кстати не знал, что коллайдер умеет генерировать меш и писал генерацию руками, спасибо, что подсказал! Надо будет сделать вторую попытку написать. * и да, лайк/подписка обязательно!
Код взятия пути с коллайдера следовало в LineFromCollider пересунуть. Этот код повторяется несколько раз и используется для подготовки данных для этого метода. Ну и как бы можно еще пару десятков замечаний сделать, по поводу качества кода и оптимизаций. Но не буду. Неплохо разобрал алгоритм, лайк, подписка.
Большое спасибо, как раз сейчас изучаю Unity для разработки игр, чтобы потом найти работу по данной специальности. Мне формулы внутри метода по поиску пересечения, прям напомнили один момент, где нужно было реализовать нажатие на 2D панель в 3D пространстве, я сначала подумал, может просто локализировать HitPos взгляда игрока относительно 2D панели, но когда увидел реализацию, там всё куда было сложнее, и очень аналогично тому, что в поиске по пересечению. Лайк и подписка :)
Вот ни разу не разработчик игр, но очень интересно смотреть такие видео, с рассуждениями, алгоритмами. Огромное спасибо автору! Лайк и подписка на канал. Пойду остальные видео смотреть) А, еще: исходники лучше все же кидать на гитхаб:)
Спасибо) А какая разница? так и так скачивать нужно один и тот же объем информации. И столько же кнопок нажимать. Ну т.е. есть некоторый процент людей, которым нужно пояснить как скачивать с гита. А есть те кто умеют и им без разницы как скачать. Вот и выбор для меня очевиден как прикрепить
Ну это конечно простой вариант алгоритма. Здесь будет очень много ошибок(которых на первый взгляд не видно), что будет приводить к полному исчезновению формы из-за ошибок триангуляции и соответственно ошибок декомпозинга для concave форм физики. Будет не очень весело если в релизной версии игры при стрельбе из гранатамёта у пользователя исчезнет пол карты. Также нет реализации отверстий внутри форм(для этого нужно будет нарезать форму на де части или более). Там очень много подводных камней из-за ошибок округления положения вершин(сохраняете в файл все вершины(всё работает), загружаете уже нет(welcome to float hell)). Вообщем что-бы сделать игру с подобным движком поверхностей, нужно не пару дней. Пол года минимум жесткой разработки и тестов.
Почему перестает работать, если подвинуть объект Land, изменив его Position в Transform? Если позиция Land не (0,0,0) - не работает. Например, если нужно добавить второй объект Land рядом с другими координатами. Как их учитывать?
Всё стало работать, если в компоненте Land.cs после _colliderRenderer.CreateMesh(); обнулять позицию коллайдера _collider.transform.position = new Vector3(0f,0f,0f); Интересно, почему так?
Объяснение просто супер! Люблю математические задачи, в часности задачи на графах! Прикольно, что ключ к решению этой проблемы - порядок следования по часовой или против часовой стрелки, чесно не подумал об этом. Скорее всего тот алгоритм, который ты нашел широко известен и используется в таких программах, как тот же фотошоп🤔 В общем огромное спасибо!
Прочти полностью) Гениально). Я искал похожий материал год назад). Я всеми 5ю руками за вторую часть ролика с оптимизацией кода. Могу тут скинуть пару вариантов. Но я не могу сам допилить и не могу избавится от бага, когда ломается меш. * Вот полу-осмысленные наброски в теории Объединить два цикла, которые перебирают сегменты landLine и CircleLine. Это сократит количество итераций вдвое. А вместо использования списка для хранения точек использовать набор хэшей. Это позволит проверить, существует ли уже точка в наборе, за постоянное время, а не за линейное время, как в случае со списком. Вместо того, чтобы перебирать точки на линиях и проверять, являются ли они пересечениями, можно создать отдельный список точек пересечения. Это позволит перебирать только пересечения, а не все точки на линиях. Можно рассмотреть возможность использования более эффективного алгоритма обнаружения пересечений, например алгоритма Бентли-Оттмана. Этот алгоритм имеет временную сложность O(n log n) для n сегментов, что может быть быстрее, чем текущий алгоритм для большого количества сегментов. Возможно использование структуры данных пространственного индексирования, такой как дерево квадрантов или дерево k-d, для хранения сегментов и быстрого поиска пересечений. Это может значительно сократить количество итераций и повысить производительность алгоритма
public List Substraction(Line landLine, Line circleLine) { // Create a list of intersection points List intersections = new List(); // Combine the two loops that iterate over the segments of the landLine and circleLine for (int l = 0; l < landLine.Segments.Count; l++) { Segment landSegment = landLine.Segments[l]; Vector2 al = landSegment.A.Position; Vector2 bl = landSegment.B.Position; for (int c = 0; c < circleLine.Segments.Count; c++) { Segment circleSegment = circleLine.Segments[c]; Vector2 ac = circleLine.Segments[c].A.Position; Vector2 bc = circleLine.Segments[c].B.Position; if (Intersection.IsIntersecting(al, bl, ac, bc)) { Vector2 position = Intersection.GetIntersection(al, bl, ac, bc); Point crossPoint = new Point(); crossPoint.Position = position; crossPoint.LandSegment = landSegment; crossPoint.CircleSegment = circleSegment; crossPoint.IsCross = true; intersections.Add(crossPoint); } } } // Use a hash set to store the points HashSet allPoints = new HashSet(landLine.Points); bool onLand = true; Point startPoint = allPoints.First(); while (allPoints.Count > 0) { Point thePoint = allPoints.First(); // Check if the point is outside the circle if (_circleCollider.ClosestPoint(thePoint.Position) == thePoint.Position || thePoint.IsCross) { allPoints.Remove(thePoint); continue; } // Collect points in a chain and assign NextPoint to them for (int i = 0; i < _testIterations; i++) { Line currentLine; // ccw -- counterclockwise bool ccw; if (onLand) { currentLine = landLine; ccw = true; } else { currentLine = circleLine; ccw = false; } int currentIndex = currentLine.Points.IndexOf(thePoint); int nextIndex = GetNext(currentIndex, currentLine.Points.Count, ccw); Point nextPoint = currentLine.Points[nextIndex]; // Check if the next point is an intersection if (nextPoint.IsCross) { onLand = !onLand; nextPoint = onLand ? nextPoint.LandSegment.OtherCrossPoint(nextPoint) : nextPoint.CircleSegment.OtherCrossPoint(nextPoint); } thePoint.NextPoint = nextPoint; allPoints.Remove(thePoint); thePoint = nextPoint; } } // Recalculate the lines with the updated points and intersections
скорей всего будет некорректно работать при реберных пересечениях, почему не использовать Clipper Library, которая специально создана для выполнения булевых операций над полигонами (объединение, пересечение, вычитание, исключающее ИЛИ) и смещения контуров полигонов на основе алгоритма Вейлера-Азертона
Огромное спасибо за пример пример проекта. Если нажимать ПКМ, то да мэш перестраивается и все отлично работает, но лишь при однократном нажатии, если же сделать изменение каждый кадр, т.е. пока кнопка зажата, чтобы как бы рисовать дыры в мэше кистью, то Юнити крашится. а алгоритм начинает неверно рассчитывать Мэш. Не решали ли Вы или кто здесь эту проблему, поделитесь пожалуйста, если удалось у кого решит ее. Заранее Спасибо.
А нет ли какого-то другого способа создавать/редактировать 2д меши, кроме как тащить их из коллайдера? Имхо меш в данном деле - первичен. И по-хорошему коллайдер при создании должен откуда-то его получать, а не раздавать.
Возможно в оригинальных червяках используется что то вроде текстуры части которой исчезают с помощью альфа канала. То есть взрыв по своей сути похож на кисточку в фотошопе. Наверно этот вариант и сейчас должен работать очень стабильно.
Интересная задача и хорошее объяснение. Но в бою (не в туториале) такой код с объектами на каждый шаг, листами, linq и тд не годится, еще нужно оптимизировать теперь все это по памяти. А так супер!
Люди которые оставляют ссылки на исходники под видео, в следующей жизни перераждаються в богатых семьях и с большим агрегатом.
В том числе, если родились девочками
Еще бы эта ссылка была бы на гитхаб - цены бы не было)
Слушай займи мне 100 тысяч клянусь я тебе миллион в следующей жизни отдам.
Очень интересная реализация интересной механики.
Также хотел сказать спасибо за бесплатный курс по разработке браузерных игр на Unity (На яндексе), тоже очень интересно и полезно!
Спасибо)
Прекрасно! Я уже пробовал подобное написать, но потом уперся в то, что на линии может быть несколько пересечений, полез исправлять, по дороге пооптимизировал производительность, и все вообще перестало работать. А потом на работе начался завал и я забросил идею реанимировать алгоритм :( Я вот кстати не знал, что коллайдер умеет генерировать меш и писал генерацию руками, спасибо, что подсказал! Надо будет сделать вторую попытку написать.
* и да, лайк/подписка обязательно!
Код взятия пути с коллайдера следовало в LineFromCollider пересунуть. Этот код повторяется несколько раз и используется для подготовки данных для этого метода.
Ну и как бы можно еще пару десятков замечаний сделать, по поводу качества кода и оптимизаций. Но не буду.
Неплохо разобрал алгоритм, лайк, подписка.
Ох не зря я подписался на этот канал. Просто недавно искал видосы про физику т.к. хотел в 3д порпактиковаться. А тут видос новый.
Большое спасибо, как раз сейчас изучаю Unity для разработки игр, чтобы потом найти работу по данной специальности. Мне формулы внутри метода по поиску пересечения, прям напомнили один момент, где нужно было реализовать нажатие на 2D панель в 3D пространстве, я сначала подумал, может просто локализировать HitPos взгляда игрока относительно 2D панели, но когда увидел реализацию, там всё куда было сложнее, и очень аналогично тому, что в поиске по пересечению. Лайк и подписка :)
Вот ни разу не разработчик игр, но очень интересно смотреть такие видео, с рассуждениями, алгоритмами. Огромное спасибо автору! Лайк и подписка на канал. Пойду остальные видео смотреть) А, еще: исходники лучше все же кидать на гитхаб:)
Спасибо) А какая разница? так и так скачивать нужно один и тот же объем информации. И столько же кнопок нажимать. Ну т.е. есть некоторый процент людей, которым нужно пояснить как скачивать с гита. А есть те кто умеют и им без разницы как скачать. Вот и выбор для меня очевиден как прикрепить
Спасибо Огромное! Давно ждал новых видео! Возможности этой механики огромные, обязательно где-то использую!
Идеально! Очень давно ждал!! Спасибо ❤
Круто, алгоритм отличный, было интересно помсмотреть. Даже захотелось в Юнити вернуться)) ты мотивируешь !
Как всегда на высоте, очень познавательно и всё по делу, браво!
Красавчик! Рад что ты стал чуть более медийным)
Ох заморочился ты конечно) Хорош 💪
Отличная новость про курс. Большое спасибо за труд!
Приятно видеть интересные видео)
Спасибо)
Ура! Снова видео начали выходить
Недавно начал смотреть твои видео, а ты в честь этого решил снять видео)
Спасибо за курс!
Очень круто, всегда хотелось это сделать но руки не доходили а тут прям как подарочек, спасибо автору !
Ну это конечно простой вариант алгоритма. Здесь будет очень много ошибок(которых на первый взгляд не видно), что будет приводить к полному исчезновению формы из-за ошибок триангуляции и соответственно ошибок декомпозинга для concave форм физики. Будет не очень весело если в релизной версии игры при стрельбе из гранатамёта у пользователя исчезнет пол карты. Также нет реализации отверстий внутри форм(для этого нужно будет нарезать форму на де части или более). Там очень много подводных камней из-за ошибок округления положения вершин(сохраняете в файл все вершины(всё работает), загружаете уже нет(welcome to float hell)). Вообщем что-бы сделать игру с подобным движком поверхностей, нужно не пару дней. Пол года минимум жесткой разработки и тестов.
очень круто это же надо в уме было всё обработать и придумать как всё будет взаимодействовать
За курс больше спасибо
Лайк и коммент в поддержку канала!😊
Почему перестает работать, если подвинуть объект Land, изменив его Position в Transform? Если позиция Land не (0,0,0) - не работает. Например, если нужно добавить второй объект Land рядом с другими координатами. Как их учитывать?
Всё стало работать, если в компоненте Land.cs после _colliderRenderer.CreateMesh(); обнулять позицию коллайдера _collider.transform.position = new Vector3(0f,0f,0f);
Интересно, почему так?
Объяснение просто супер!
Люблю математические задачи, в часности задачи на графах!
Прикольно, что ключ к решению этой проблемы - порядок следования по часовой или против часовой стрелки, чесно не подумал об этом.
Скорее всего тот алгоритм, который ты нашел широко известен и используется в таких программах, как тот же фотошоп🤔
В общем огромное спасибо!
Круто, даже курс, ну все) мир, жди моих игр)
5 точка ! лучший ! ;) спасибо за видосы ! Продолжай радовать нас своими шуткосами ;)
Спасибо)
Очень жду каких-нибуть еще уроков)
Классные ролики. Очень интересно. Развивай тему! Что-то типа "игра за полчаса"
главное не скорость, а качество!
Прочти полностью)
Гениально). Я искал похожий материал год назад). Я всеми 5ю руками за вторую часть ролика с оптимизацией кода. Могу тут скинуть пару вариантов. Но я не могу сам допилить и не могу избавится от бага, когда ломается меш.
* Вот полу-осмысленные наброски в теории
Объединить два цикла, которые перебирают сегменты landLine и CircleLine. Это сократит количество итераций вдвое.
А вместо использования списка для хранения точек использовать набор хэшей. Это позволит проверить, существует ли уже точка в наборе, за постоянное время, а не за линейное время, как в случае со списком.
Вместо того, чтобы перебирать точки на линиях и проверять, являются ли они пересечениями, можно создать отдельный список точек пересечения. Это позволит перебирать только пересечения, а не все точки на линиях.
Можно рассмотреть возможность использования более эффективного алгоритма обнаружения пересечений, например алгоритма Бентли-Оттмана. Этот алгоритм имеет временную сложность O(n log n) для n сегментов, что может быть быстрее, чем текущий алгоритм для большого количества сегментов.
Возможно использование структуры данных пространственного индексирования, такой как дерево квадрантов или дерево k-d, для хранения сегментов и быстрого поиска пересечений. Это может значительно сократить количество итераций и повысить производительность алгоритма
public List Substraction(Line landLine, Line circleLine)
{
// Create a list of intersection points
List intersections = new List();
// Combine the two loops that iterate over the segments of the landLine and circleLine
for (int l = 0; l < landLine.Segments.Count; l++)
{
Segment landSegment = landLine.Segments[l];
Vector2 al = landSegment.A.Position;
Vector2 bl = landSegment.B.Position;
for (int c = 0; c < circleLine.Segments.Count; c++)
{
Segment circleSegment = circleLine.Segments[c];
Vector2 ac = circleLine.Segments[c].A.Position;
Vector2 bc = circleLine.Segments[c].B.Position;
if (Intersection.IsIntersecting(al, bl, ac, bc))
{
Vector2 position = Intersection.GetIntersection(al, bl, ac, bc);
Point crossPoint = new Point();
crossPoint.Position = position;
crossPoint.LandSegment = landSegment;
crossPoint.CircleSegment = circleSegment;
crossPoint.IsCross = true;
intersections.Add(crossPoint);
}
}
}
// Use a hash set to store the points
HashSet allPoints = new HashSet(landLine.Points);
bool onLand = true;
Point startPoint = allPoints.First();
while (allPoints.Count > 0)
{
Point thePoint = allPoints.First();
// Check if the point is outside the circle
if (_circleCollider.ClosestPoint(thePoint.Position) == thePoint.Position || thePoint.IsCross)
{
allPoints.Remove(thePoint);
continue;
}
// Collect points in a chain and assign NextPoint to them
for (int i = 0; i < _testIterations; i++)
{
Line currentLine;
// ccw -- counterclockwise
bool ccw;
if (onLand)
{
currentLine = landLine;
ccw = true;
}
else
{
currentLine = circleLine;
ccw = false;
}
int currentIndex = currentLine.Points.IndexOf(thePoint);
int nextIndex = GetNext(currentIndex, currentLine.Points.Count, ccw);
Point nextPoint = currentLine.Points[nextIndex];
// Check if the next point is an intersection
if (nextPoint.IsCross)
{
onLand = !onLand;
nextPoint = onLand ? nextPoint.LandSegment.OtherCrossPoint(nextPoint) : nextPoint.CircleSegment.OtherCrossPoint(nextPoint);
}
thePoint.NextPoint = nextPoint;
allPoints.Remove(thePoint);
thePoint = nextPoint;
}
}
// Recalculate the lines with the updated points and intersections
друг, я весь твой коммент заскринил и в рамочку сейчас вставлю, xD
😅 жесть я тут расписал)) не помню уже@@Scriberrot
Илья выпускает новый ролик.
Синоптики объявляют неделю игр про червячков, игры с похожей механикой будут выходит в два раза чаще ))
Очень круто! Ты молодец! 🔥
Привет ,классный ролик!
Спасибо)🐛
крутое видео, спасибо за старания
Спасибо за туториалы которые делаешь) рад видеть успехи)
Amazing! Thanks for this content!
Ого, какой классный новый урок!
Приятно было снова услышать от тебя полезную и интересную информацию)
круто, как всегда)
Это мегоофигенно!)
Спасибо большое!!
Интересный проект и реализация 👍👍👍
Очень круто!
А в 3D с видом сверху можно тоже так или там другой подход нужен?
скорей всего будет некорректно работать при реберных пересечениях, почему не использовать Clipper Library, которая специально создана для выполнения булевых операций над полигонами (объединение, пересечение, вычитание, исключающее ИЛИ) и смещения контуров полигонов на основе алгоритма Вейлера-Азертона
Классно было бы посмотреть продолжение, как ты делал б из техно-демки в рабочую игру
хотел лечь пораньше, но видно не судьба
Офигеть... Спасть отменяется :)
Круто конечно)))
Огромное спасибо за пример пример проекта. Если нажимать ПКМ, то да мэш перестраивается и все отлично работает, но лишь при однократном нажатии, если же сделать изменение каждый кадр, т.е. пока кнопка зажата, чтобы как бы рисовать дыры в мэше кистью, то Юнити крашится. а алгоритм начинает неверно рассчитывать Мэш. Не решали ли Вы или кто здесь эту проблему, поделитесь пожалуйста, если удалось у кого решит ее. Заранее Спасибо.
А смог бы сделать гонки с физикой как в F-Zero?)
А нет ли какого-то другого способа создавать/редактировать 2д меши, кроме как тащить их из коллайдера? Имхо меш в данном деле - первичен. И по-хорошему коллайдер при создании должен откуда-то его получать, а не раздавать.
Коллеги, кто знает: в стим можно выпустить бесплатную игру со встроенной рекламой или там это запрещено?
тоже интересно 😅
Чувак ты крутой!
Илья лучший
Спасибо! И ты лучший)
Хм, интересно а насколько производительно будет в трехмерном пространстве
смотря сколько точек у вырезающей фигуры)
Неожиданно)
Блин где же ты год назад был…
Круто!
Можно реализовать достаточно быстрый метод с пикселями, нужно только знать как пользоваться вычислительными шейдерами)
@@СветозарБоголюбов все там же, в вычислительных шейдерах
Интересно , как они это на sega сделали
там подмена спрайта с помощью маски, как я себе это представляю
Красавчик!
Изобрёл Boolean)
All my childhood in one video
о круто с яндексом калаба)
Оч круто
Очень сложно... я мозг взорвал..., но оторваться не могу
Давай Worms в 3D.
Шо делать если на виеде 7 не работает вс2019, точнее он вообще нехочет скачиватся
Теперь чмыри Сакутина, как он чмырит Хауди Хо.
Благородный человек не смеётся над юродивами.
Так говорил Конфуций
😂
Они друзья, на сколько я помню)
@Вин Ты назвал его глупцом, но сделал это без уважения)))
Блин, наверное прошу много, но было бы лучше ссылку на гитхаб, что бы не качать проект)
Отсыпьте лукасов, да побольше!))
Возможно в оригинальных червяках используется что то вроде текстуры части которой исчезают с помощью альфа канала. То есть взрыв по своей сути похож на кисточку в фотошопе. Наверно этот вариант и сейчас должен работать очень стабильно.
почему всё на гениальном языке?
Вормс с нуля за два дня?! Это точно туториал? Или просто психологическое уничтожение средненьких разработчиков?
Создал булевы операции с нуля
Привет
Интересная задача и хорошее объяснение. Но в бою (не в туториале) такой код с объектами на каждый шаг, листами, linq и тд не годится, еще нужно оптимизировать теперь все это по памяти.
А так супер!
как то сложно ты решил сделать, должно быть все гораздо проще
прошел б курс но изза яндекса не буду