Пятница, 29 Марта 2024, 13:47

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Склейка спрайтов в реальном времени (Или каких костылей только не найдешь)
Склейка спрайтов в реальном времени
harmoxyneДата: Среда, 01 Апреля 2015, 22:45 | Сообщение # 1
заслуженный участник
Сейчас нет на сайте
И так, всем привет.
Появилась такая проблема, решить которую адекватными методами у меня не получилось.
Дано: 2Д-игра, нарисованная спрайтами. Спрайты живут в спрайтшитах. Есть разные спрайты. Нужно при определенных условиях их склеивать, дабы с анимацией не было проблем.

И так, ежели кратко, банальный пример:


Я взял первый спрайтшит, разрезал его на отдельные спрайты, сделал анимацию в меканиме (выглядит это, конечно, ужасно)

(Если кто знает, как сделать это эргономичней, буду рад совету).

Потом появилась необходимость напялить на нашего персонажа доспехи (негоже щеголять с голой задницей по полям битвы). И вот тут-то я столкнулся с проблемой: а как, собственно?
Был вариант такой: создать дочерний ГО персонажу, на него ещё один аниматор, спрайт рендер, разрезать каждый из спрайтшитов на отдельные спрайты, сделать им анимацию (загнать в префабы, например), и потом, при необходимости, создавать его на персонаже. Но, эта идея была отброшена, ибо крайне долго и мучительно (если два спрайтшита, то ничего, но если их десятки сотен, то трудненько).
Был и такой вариант: сделать несколько спрайт рендеров на персонаже, в каждый из них бросать нужный спрайт, и так далее, но по причине бредовости была отброшена.
Появился более-менее приемлимый, как по мне, вариант: у нас есть некая заготовка (первый спрайтшит), с которым игрок приходит в этот мир. По мере нахождения чего-либо, к нему приклеивается спрайтшит нужной вещи. При чем в прямом смысле. Просто накладывается сверху на спрайтшит-заготовку, и используется для анимации. Как мне кажется, это был бы самый приемлимый вариант, но как такое реализовать я не знаю.
Потому, уважаемые форумчане, либо пните меня в направлении реализации моей идеи, либо пните придумывать дальше что-то адекватное.
Заранее спасибо.
MANMANAДата: Среда, 01 Апреля 2015, 22:53 | Сообщение # 2
почти ветеран
Сейчас нет на сайте
Цитата QNicolya ()
По мере нахождения чего-либо, к нему приклеивается спрайтшит нужной вещи. При чем в прямом смысле. Просто накладывается сверху на спрайтшит-заготовку, и используется для анимации. Как мне кажется, это был бы самый приемлимый вариант, но как такое реализовать я не знаю.


смотрим на твой листок и видим, что в некоторых местах наложенный лут будет закрывать ту же руку. как будешь выкручиваться?:)
сильно не вдавался в детали 2d, но делать раздельными определенные части персонажа, либо как в fallout, т.е. рисуем все в каждом шмоте

Добавлено (01 апреля 2015, 22:53)
---------------------------------------------
разделение на части позволит подсовывать шпот поверх тела, но под другие части тела. слои которых придется менять согласно ориентации игрока.
мож есть готовые ассеты?


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею


Сообщение отредактировал MANMANA - Среда, 01 Апреля 2015, 22:52
harmoxyneДата: Среда, 01 Апреля 2015, 22:59 | Сообщение # 3
заслуженный участник
Сейчас нет на сайте
Цитата MANMANA ()
мож есть готовые ассеты?

Вот сейчас задался этим вопросом, ищу smile
Цитата MANMANA ()
смотрим на твой листок и видим, что в некоторых местах наложенный лут будет закрывать ту же руку

Можно посмотреть тут на принцип действия, нужно именно что-то в таком стиле.
Если все спрайтшиты нарисованы в одном размере и порядке, проблем с перекрытием возникнуть не должно smile
MANMANAДата: Среда, 01 Апреля 2015, 23:10 | Сообщение # 4
почти ветеран
Сейчас нет на сайте
игрался я как-то в Stone of Life http://www.youtube.com/watch?v=bG5GCcTG-J8 там много лута разного. реализовано частями smile

Добавлено (01 апреля 2015, 23:10)
---------------------------------------------
наверное


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
harmoxyneДата: Четверг, 02 Апреля 2015, 01:20 | Сообщение # 5
заслуженный участник
Сейчас нет на сайте
MANMANA, но реализация частями меня не устраивает, ибо требует слишком много сил. Потому хотелось бы что-то приближенное к тому, что я предложил.

Добавлено (02 апреля 2015, 01:20)
---------------------------------------------
Пока что решил эту беду с помощью .GetPixels, .SetPixels, однако склейка 7 спрайтшитов проходит целых 6-10 секунд, что, в принципе, не особо приемлимо.
Если кто знает способ лучше, подскажите?
Код
void CombineTextures(Texture2D newTexture, Texture2D mainTexture, Texture2D overlay)
{

var offset = new Vector2(((newTexture.width - overlay.width)/2), ((newTexture.height - overlay.height)/2));

newTexture.SetPixels(mainTexture.GetPixels());

for(var y = 0; y < overlay.height; y++)
{
for(var x = 0; x < overlay.width; x++)
{
var pixelColorFore = overlay.GetPixel(x, y)*overlay.GetPixel(x, y).a;
var pixelColorBack = newTexture.GetPixel(x + Mathf.RoundToInt(offset.x), y + Mathf.RoundToInt(offset.y)) * (1 - pixelColorFore.a);
newTexture.SetPixel(x + Mathf.RoundToInt(offset.x), y + Mathf.RoundToInt(offset.y), pixelColorBack + pixelColorFore);
}
}

newTexture.Apply();
}


Сообщение отредактировал QNicolya - Четверг, 02 Апреля 2015, 01:21
NovaSurferДата: Четверг, 02 Апреля 2015, 01:44 | Сообщение # 6
частый гость
Сейчас нет на сайте
Цитата QNicolya ()
Был вариант такой: создать дочерний ГО персонажу, на него ещё один аниматор, спрайт рендер

Вы почти правы, но я бы сделал так:

//.. когда твой перс наткнулся на сундук и оттуда выпали доспехи.
1] Создал новый объект на сцене прямо во время игры(как child для голенького персонажа используя transform.parent)
2] На этот объект цепляем spriteRenderer, а в него нужную тебе картинку(с доспехами).
2](C анимацией геморра становится больше, а может и нет..) Вешаешь на объект Animator(если ты используешь mecanim), в него вешаешь controller.

Все вышеперечисленное пилите отдельным классом, с методами, которые ставят spriteRenderer и Animator вам на объект. Эти методы на вход берут Sprite и Controller
для spriteRenderer и Animator соответственно. Потом уже из другого места (скрипта/класса) в котором есть два массива или списка (лучше брать массив если вы не собираетесь туда ничего добавлять по ходу игры). Первый массив со спрайтами предметов, второй - контроллерами.
При смене доспехов объект можно(или нужно) удалять. Если хотите пред удалением что-то передать (например у вас реализован уровень поношенности предмета) используйте OnDestroy().
Пишите если что.

P.S. Я тут подумал, что при смене предмета лучше не удалять объект, а просто отключать, потому что мне кажется создавать каждый раз новый объект и цеплять на него компоненты по ходу игры это не есть гуд. Например:
У вас в инвентаре 5 слотов(все занято мечами lol)
Один меч (шестой) у вас в руках(то есть он enabled все остальные disabled)
И тут вы решаете, что нафиг сдался вам один из мечей. Швыряете его на пол(он вылетает из child'a вашего перса и animator выключается)
Потом вы думаете, что нет, пропадет зазря, лучше продать. Подбираете меч и все как при швырке на пол только наоборот, ну и нужную вам позицию выставляете.

P.S.S. Я может (точно) с мечами и инвентарем перегнул, хотя если вы делаете убийцу Diablo, то после создания объекта предмета, его ID и уровень поношенности лучше (я так думаю) куда-то записывать (конечно если им еще можно воспользоваться), а объект удалять.

А вообще, надо будет почитать (но завтра), что жрет больше создание/удаление GameObject'ов в риалтайме или 100+ disabled child'ов. Я думаю, что child'ы, но с ними не надо постоянно записывать/читать характеристики предмета, который использовался раньше, потому что если мы удалили объект, то после создания он должен иметь такие же характеристики как и после его удаления (конечно если он был в рабочем состоянии), но это не так уж и сложно реализовать.
Исправьте, если в чем-то не прав.

ПАРДОН:
Не знал что вы пишите на JS, тогда по поводу массивов и списков ничего вам сказать не могу :). Но если мне память не изменяет, то в JS можно пушать новые элементы прямо в массив.


Мой блог - infcode.com

Сообщение отредактировал NovaSurfer - Четверг, 02 Апреля 2015, 01:52
OrdanДата: Четверг, 02 Апреля 2015, 02:31 | Сообщение # 7
Главный зомби
Сейчас нет на сайте
Я бы рисовал все поверх персонажа. Отрисовывал бы доспехи отдельным спрайтом и рисовал его поверх персонажа.

Цитата недели: Из-за леса, из-за гор, кишки, месиво, хардкор. (Берсерк ТВ-2)

Мои проекты ТЫК
Мои видяхи на ютубэ ТЫК

Если ты споришь с идиотом, вероятно тоже самое делает и он.
harmoxyneДата: Четверг, 02 Апреля 2015, 10:56 | Сообщение # 8
заслуженный участник
Сейчас нет на сайте
Цитата NovaSurfer ()
Не знал что вы пишите на JS,

Это C#, в нём тоже можно использовать var, и иногда это весьма удобно.

Цитата Ordan ()
Я бы рисовал все поверх персонажа. Отрисовывал бы доспехи отдельным спрайтом и рисовал его поверх персонажа

Это и предполагал мой первый способ, но, как я уже сказал, придется разрезать каждый спрайтшит отдельно, делать ему анимацию, и если у меня их штук 40, то это ещё ничего, а когда их количество вырастет до нескольких сотен, то всё будет очень плохо.
Тем более, это же придется к каждому объекту делать такую же страшную схему анимаций, как у главного персонажа.
Пока попробую поиздеваться над тем методом, есть пару идей как его оптимизировать. А то он действует сурово: просто вешает игру на 7-10 секунд, и потом возвращает.

Добавлено (02 апреля 2015, 10:56)
---------------------------------------------
Сделал вывод, что даже с корутинами, получается слишком долгая задержка, потому нужно что-то другое.
Что же, если ни у кого не будет других вариантов, придется костылять отдельными ГО.

NovaSurferДата: Четверг, 02 Апреля 2015, 15:10 | Сообщение # 9
частый гость
Сейчас нет на сайте
Вот то, что хотите сделать вы. КЛАЦ
Вот приблизительно то, о чем писал я. КЛАЦ
Прошу заметить, что парень, который написал ответ про склеивание спрайтов в рантайме (первая ссылка), отметил, что это очень громоздкий для железа процесс.


Мой блог - infcode.com

Сообщение отредактировал NovaSurfer - Четверг, 02 Апреля 2015, 15:10
harmoxyneДата: Четверг, 02 Апреля 2015, 15:18 | Сообщение # 10
заслуженный участник
Сейчас нет на сайте
NovaSurfer, первую ссылку находил, читал. Сути действий по второй ссылке я не понял, надо будет посмотреть внимательнее.
NovaSurferДата: Четверг, 02 Апреля 2015, 15:25 | Сообщение # 11
частый гость
Сейчас нет на сайте
Прошу прощения, вторая ссылка это немного не то.
Там есть главный объект, который обращается к объекту с текстурой и режет из нее спрайты создавая новые объекты и пихая их как дочерние к главному.


Мой блог - infcode.com

Сообщение отредактировал NovaSurfer - Четверг, 02 Апреля 2015, 15:34
LertmindДата: Четверг, 02 Апреля 2015, 18:08 | Сообщение # 12
заслуженный участник
Сейчас нет на сайте
QNicolya, чтобы не создавать кучу Animator Controller можно попробовать в начало каждого AnimationClip добавить AnimationEvent, который будет вызывать функцию, проигрывающую соответствующие клипы для доспехов. На счёт этого не уверен, просто предположение.

Это тема, где обсуждается как не делать кучу AnimationClip вручную, если изменяются только спрайты. Что интересно, один из разработчиков Unity там сообщил, что нет нормального способа для этого в движке и похоже с того сообщения ничего не изменилось. Один человек предлагает отказаться от Mecanim (что является одним из логичных способов) и использовать SpriteManager.


Сообщение отредактировал Lertmind - Четверг, 02 Апреля 2015, 18:33
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Склейка спрайтов в реальном времени (Или каких костылей только не найдешь)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг