Откол круглого куска от круглого объекта

Допустим у меня есть круглый объект. Планета или яблоко...

И я хочу, чтобы от него во время игры "отстрелили", "отгрызли" или любым другим способом отделили круглый (или овальный) кусок. Выглядеть это должно как-то так:

введите сюда описание изображения

Естественно с физикой.

Такое может происходить много раз и, теоретически, отстрелена может быть даже часть уже отстреленного куска. Как такое можно реализовать?

Вот нашел такую иллюстрацию:

введите сюда описание изображения


Ответы (3 шт):

Автор решения: Yaroslav

Проще сделать себе ритуальное судоку, чем резать меш на осколки в реальном времени (Procedural Destruction). Так ОЧЕНЬ редко делают и только с знанием дела в ААА играх, типа Control от Remedy.

Объект нужно резать заранее. В 3d редакторах есть такие функции, например в Blender. Пока сфера цела, это самая обычная сфера для экономии. При хите она подменяется на подготовленный чанк ассет и части её статическим элементам в неком радиусе хита даем rigidbody с неким addForce и можно добавить партиклс.

Если нужны осколки которые можно будет ещё раз раскалывать то елементы в радиусе нужно будет каким-нибудь образом групировать c общим rigidbody. А если после раскола грппы, расколотая группа состоит из одного элемента для продолжения ощущения разрушаемости можно тупо заканчивать это дела партиклами и дымкой.

Идея группирования:

Создаешь компонент с полем [SerializeField ] private List<KeyValue<int ,int>> _graph в котором будет справочник-граф кусков с InstanceID(Min), InstanceID(Max). Пишуш кастумны редактор, по нажатию кнопки берет список структур с координатами центов и id <Vector3, int>, триангулирует и заполняет наш справочник, EditorUtility.SetDirty(target) и готово. По этому заранее подготовленному графу можно будет делать грппы из соседних осколков.

Даже так гемороя выше крыши ?. Удачи, счастливых выходных ?.

Но проделав это однажды можно будет создавать разрушаемые объекты конвеерно. Ассет из целой модела, чанк осколков с графом связей и набор эффектов частиц под хит, раскол и уничтожения осколка.

→ Ссылка
Автор решения: Yaroslav

По поводу вдавливания. Создай список структуры <(int)MeshVertextIndex, (float)IndentationValue>. В неком радиусе хита найди все точки меша и модифицируй вдавливание (IndentationValue) в зависимости от дальности от эпицентра, можно ещё с применением шума для красоты.

Есть два варианта реализации:

Использовать BumpMap. По uv координатам наших MeshVertextIndex можно генерировать карту бампа. Но бамп слегка устарел.

Написать шейдер. В vert функции модифицировать каждый вертекс по его нормали в обратном направлении как в этом примере Normal Extrusion with Vertex Modifier. Передаем в шейдер массив IndentationValue, а что бы узнать индекс каждой вершины в шейдере используй Vertex ID: SV_VertexID.

→ Ссылка
Автор решения: Yaroslav

Создай новый Texture2d тех-же размеров. Перенеси имеющуюся текстуру. В квадрате шириной 2*blowRadius с центров в точке хита(придется посчитать) по дистанции поменяй альфу пиксели на 0. Отдельно обработай края что-бы не было резкого алайзинга.

Создай новый спрайт из этой текстуры. PolygonCollider2D останется старый, для перещёта удали компонент и добавь заново.

Не забывай уничтожать старые сгенерированные текстуры при генерации новых или уничтожении объекта Destroy(texture), что бы не засерать память.

→ Ссылка