Гайд по моддингу
- Введение
- Папка модификаций
- Метаданные
- meta.yaml
- resources.yaml
- Описание
- backdrop_bg
- backdrop_text
- bg
- cg
- catalogs
- characters
- chibis
- collections
- colors
- entryPoint
- help
- live2d_characters
- menu
- narrators
- notes
- particles
- positions
- scenarios
- sizes
- spritecolor
- sound
- transitions
- variables
- Мод-пример
- Запуск модов
- Готовый проект Unity
- Создание каталогов
- Импорт Live2D-моделей
- Исходники Live2D-спрайтов для Unity
- Переводы сценариев
- Загрузка мода в Steam Workshop
- Миграция со старой системы модов
- Баги и обратная связь
Введение
Итак, вы решили написать мод для Love, Money, Rock'n'Roll.
По большей части вам понадобится любой текстовый редактор (желательно с поддержкой YAML-синтаксиса) — например, Notepad++, однако хватит и обычного блокнота.
Папка модификаций
Все локальные модификации для игры подгружаются из папки Love, Money, Rock'n'Roll_Data\mods
.
Моды из Steam Workshop хранятся внутри папки steamapps\workshop\content\615530
, которая расположена на том диске, на котором установлена игра.
Сам мод может храниться в двух видах:
- В подпапке
- В zip-архиве с расширением .scenario
.scenario-архивы предназначены преимущественно для распространения модификаций вне Steam Workshop.
Steam Workshop поддерживает только моды в подпапках, любые другие моды (в .scenario-архивах или .mod-бандлах из старой системы модов) не будут распознаваться игрой.
Подобное ограничение нужно для корректного распознавания мастерской изменений в файлах модификации.
Метаданные
Файлы метаданных
Игра получает информацию о моде из следующих файлов:
meta.yaml
resources.yaml
meta.yaml
отвечает за информацию о моде во внутриигровом мод-селекторе;resources.yaml
— за всё остальное — это основной файл, который вам придётся редактировать чаще всего.
Оба файла должны быть расположены в корневой директории мода, содержимое файлов должно иметь корректный YAML-синтаксис и верно указанные параметры (об этом будет далее).
YAML достаточно простой и интуитивный, но если у вас возникли сложности, можете воспользоваться специальным ресурсом для валидации YAML-синтаксиса.
В YAML нельзя использовать табуляцию — используйте пробелы.
Языковые ноды
Некоторые параметры могут иметь переводы на несколько языков, такие параметры далее будут называться языковыми нодами.
Значением такого параметра может быть просто текст:
title: Название мода
В таком случае Название мода
будет отображаться на русском для всех языков.
Чтобы локализировать параметр для разных языков, нужно указать код языка и текст:
title:
ru: Название мода
en: Mod title
common: Текст, который будет выводиться для любого другого языка*, перевод для которого не указан
Поддерживаемые языковые коды:
ru
— русскийen
— английский
* В игре на данный момент всего два языка — русский и английский.
Ресурсные ноды
Большая часть параметров в resources.yaml
определяет какие-либо внешние ресурсы, используемые в игре: фоны, звуки, спрайты персонажей и их имена, цвета, глобальные переменные и прочее. Такие параметры для удобства будут называться ресурсными нодами.
Каждому такому параметру должен быть назначен уникальный ID — имя, на которое вы будете ссылаться при написании сценария для использования данного ресурса.
У таких имён есть ограничения на используемые символы, а именно: допускаются только латинские (английские) символы, цифры и нижнее подчёркивание. Использовать кириллицу, пробелы или какие-то либо другие символы нельзя.
Пример определения фона с ID bus_stop
внутри resources.yaml
:
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg
Строчка bus_stop: bg/bus_stop.jpg
— ресурсный нод, содержащий путь к ассету.
Пример определения цвета с ID dark_pink
:
# resources.yaml
---
colors:
dark_pink: #b00b69
ID регистронезависимы
Ассеты
Пути ассетов
Различные ноды часто принимают в качестве аргумента путь к какому-либо ассету (файлу).
Все пути к ассетам, загружаемым из директории мода, должны быть относительными, т.е. должны указываться без пути к корневой папке мода.
Например, у нас есть обложка мода — cover.jpg, которая лежит в папке images. Корректный путь к ней будет выглядеть так:images/cover.jpg
Если же обложка лежит в корневой директории, достаточно просто указать имя файла:cover.jpg
Если ваш мод находится внутри .scenario-архива, учитывайте регистр при указании путей. Также регистр важен на UNIX-системах (Linux, macOS, Android и т.п.).
Если ваш файл называется Cover.jpg, а в пути вы указали cover.jpg — будет выдана ошибка.
Виды ассетов
Всего существует 3 основных вида ассетов, их можно загружать из директории мода и из Unity-каталогов:
texture
— графический ассетtext
— текстовый ассетsound
— звуковой ассет
Также существует ещё 2 вида, которые можно загружать только из Unity-каталогов:
prefab
— Unity-префабsprite
— Unity-спрайт
У каждого параметра, принимающего ассет(ы) в качестве аргумента, будут указаны виды ассетов, которые он принимает.
Списки
Большая часть основных параметров — это списки, т.е., ноды, которые содержат в себе наборы других однотипных нодов.
Например:
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg
ext_road_day: bg/ext_road_day.jpg
sound:
blow_with_the_fires: sound/blow_with_the_fires.ogg
no_tresspassing: sound/no_tresspassing.ogg
Параметры bg
и sound
в данном примере — списки.
meta.yaml
Файл с основной информацией о модификации. По наличию этого файла в подпапке / .scenario-архиве игра распознает мод.
Внутри файла указываются название мода, описание, версия и обложка для внутриигрового мод-селектора.
Содержимое файла имеет следующий вид:
---
title: Название мода
description: Описание мода
version: 1.0.0
cover: cover.jpg
Наличие любого из параметров необязательно, однако сам файл (пусть даже и пустой) обязательно должен быть в корневой папке мода, чтобы мод распознался игрой.
Параметры
title
Тип: языковой нод
Название мода. Поддерживает тэги разметки Rich Text.
description
Тип: языковой нод
Описание мода. Поддерживает тэги разметки Rich Text.
version
Тип: текстовый нод
Версия мода. Выводится в правом нижнем углу обложки.
cover
Обложка мода.
Файл обложки должен весить не более 2048 килобайт.
Предпочтительное разрешение: 445x200.
resources.yaml
Описание
Файл, содержащий информацию о всех ресурсах мода. Именно в нём прописываются все невстроенные в игру ресурсы, которые вы хотите использовать в игре.
Поддерживает следующие параметры:
- backdrop_bg
- backdrop_text
- bg
- cg
- catalogs
- characters
- chibis
- collections
- colors
- entryPoint
- help
- live2d_characters
- menu
- narrators
- notes
- particles
- positions
- scenarios
- sizes
- spritescolors
- sound
- transitions
- variables
Большая часть из этих параметров — списки, внутри которых прописываются те или иные ресурсы.
backdrop_bg
Тип: список ресурсных нодов
Типы принимаемых ассетов:
texture
— тип по умолчаниюsprite
prefab
Определяет фоны для команды backdrop.
Пример использования:
# resources.yaml
---
backdrop_bg:
eli_1: backdrops/eli_1.jpg
himitsu_2: backdrops/himitsu_2.jpg
kagome_3: ~@bundle[prefab]://backdrop_kagome_3.prefab #подгрузка префаба из каталога "bundle"
backdrop_text
Тип: список языковых нодов
Определяет локализируемый текст для команды backdrop.
Пример использования:
# resources.yaml
---
backdrop_text:
day1: День 1
day2:
ru: День 2
en: Day 2
day3: День 3
bg
Тип: список ресурсных нодов
Типы принимаемых ассетов:
texture
— тип по умолчаниюsprite
prefab
Определяет фоны для команды scene.
Ноды данного параметра могут принимать путь к одному или нескольким ассетам:
# resources.yaml
---
bg:
ext_road_day: bg/ext_road_day.jpg
В таком случае указанный ассет — bg/ext_road_day.jpg
— будет использоваться вне зависимости от настроек анимации фонов в игре.
Чтобы задать разные ассеты для разных настроек анимации, следует указывать пути внутри параметров static
и anim
:
# resources.yaml
---
bg:
ext_road_day:
static: bg/ext_road_day.jpg
anim: ~@bundle[prefab]://bg/ext_road_day.prefab #префаб анимированного фона из каталога "bundle"
int_bus_day:
static: bg/int_bus.jpg
anim: bg/int_bus_2.jpg #статичное изображение, однако оно будет использоваться, если в настройках игры включена анимация фонов
Если один из параметров не указан (static
или anim
), то в обоих режимах будет использоваться ассет указанного параметра.
cg
Тип: список ресурсных нодов
Типы принимаемых ассетов:
texture
— тип по умолчаниюsprite
prefab
Определяет цг для команды scene.
Синтаксис полностью идентичен bg, отличается только название нода:
# resources.yaml
---
cg:
d1_rena_sunset: cg/d1_rena_sunset.jpg
d3_dv_guitar:
static: cg/d3_dv_guitar.jpg
anim: ~@bundle[prefab]://cg/d3_dv_guitar.prefab
catalogs
Тип: список ресурсных нодов
Определяет Unity-каталоги для загрузки ассетов.
В нодах указывается путь к .json
файлу собранного каталога:
# resources.yaml
---
catalogs:
bundle: catalogs/bundle/catalog.json #определение каталога "bundle"
Каталог должен лежать внутри папки мода и не может находится внутри другого каталога
Также можно указать каталоги для разных платформ:
# resources.yaml
---
catalogs:
bundle: #определение каталога "bundle" под разные платформы
windows: catalogs/bundle/win/catalog.json
linux: catalogs/bundle/linux/catalog.json
macos: catalogs/bundle/mac/catalog.json
android: catalogs/bundle/android/catalog.json
ios: catalogs/bundle/ios/catalog.json
Список доступных плафторм:
windows
linux
macos
android
ios
Если платформа не указана (как в первом примере), то будет выставлено значение по умолчанию — windows
.
После определения каталога, вы можете использовать ассеты из него при помощи следующего синтаксиса:~@имяКаталога://адресАссета
Тип ассета указывается в квадратных скобках после имени каталога:~@имяКаталога[типАссета]://адресАссета
Если тип не указан, будет использован тип по умолчанию в зависимости от параметра.
Примеры использования путей с каталогом "bundle":~@bundle://bg/bus_stop # ассет с адресом bg/bus_stop из каталога
~@bundle[prefab]://bg/bus_stop # префаб с адресом bg/bus_stop из каталога
characters
Тип: список
Определяет статичные спрайты персонажей для команды show.
Внутри нода прописываются ноды с параметрами статичных (неанимированных) спрайтов персонажей:
# resources.yaml
---
characters:
dv:
# ... параметры
un:
# ... параметры
sl:
# ... параметры
us:
# ... параметры
Каждый спрайтовый нод может содержать следующие параметры:
poses
positions
sizes
shortnames
default
poses
Тип: список
Определяет позы спрайта.
Под позами понимаются различные вариации спрайта:
3 различных позы на примере спрайта из Бесконечного Лета
Каждая поза может содержать несколько параметров:
parts
— обязательный параметрcanvasSize
positions
sizes
spritecolors
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
# ... параметры
canvasSize: 900 1080
positions:
# ... параметры
sizes:
# ... параметры
spritecolors:
# ... параметры
parts
Тип: список
Определяет части, из которых собирается спрайт.
Части могут быть двух типов:
- постоянные
- непостоянные
Тип ассетов у частей — texture
.
Постоянные части
Постоянные части видны всегда и никогда не меняются (например, тело персонажа).
Определяются следующим образом:
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
body: sprites/mt/mt_1_body.png # тело персонажа, которое должно отображаться всегда
# ... остальные параметры
На примере выше мы определили часть body
— тело спрайта, на которое будут накладываться остальные элементы.
Непостоянные части
Непостоянные — соответственно, те части, которые могут меняться. Это эмоции, одежда, различные аксессуары и прочее. Такие части объединяются в группы, которые позволяют менять активную (отображаемую) часть из сценария.
Непостоянные части определяются так же, как и постоянные, только внутри отдельного нода, начинающегося со знака ~
— такой нод называется группой:
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
body: sprites/mt/mt_1_body.png # это постоянная часть, которую мы определили ранее
~uniform: # группа uniform
pioneer: sprites/mt/mt_1_pioneer.png # пионерская форма
dress: sprites/mt/mt_1_dress.png # платье
swimsuit: sprites/mt/mt_1_swim.png # купальник
# ... остальные параметры
У частей спрайта в группе также может указываться параметр position
, синтаксис аналогичен.
На примере выше мы создали группу uniform
с различными вариациями одежды, которые можно использовать в игре. Однако мы не указали, какая часть должна отображаться по умолчанию — в случае, если мы явно не обозначили это в сценарии.
Чтобы сделать какую-либо часть в группе частью, отображаемой по умолчанию, можно воспользоваться параметром default
:
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
body: sprites/mt/mt_1_body.png # это постоянная часть, которую мы определили ранее
~uniform: # группа uniform
default: pioneer # по умолчанию при вызове спрайта будет выводиться пионерская форма
parts:
pioneer: sprites/mt/mt_1_pioneer.png # пионерская форма
dress: sprites/mt/mt_1_dress.png # платье
swimsuit: sprites/mt/mt_1_swim.png # купальник
# ... остальные параметры
Как видно из примера, ID части, выводимой по умолчанию, прописывается в ноде default
, а сами части — в parts
.
Если нод default
не указан, то по умолчанию ни одна часть не будет выводиться.
Позиционирование частей
Каждой части спрайта можно задать положение относительно канваса:
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
body:
asset: sprites/mt/mt_1_body.png
position: 0 100
# ... остальные параметры
На примере выше изображение будет смещено на 100 пикселей по вертикали относительно левого верхнего угла канваса спрайта. Ассет же прописывается в ноде asset
.
Использование параметра position
у части спрайта возможно только если указан параметр canvasSize
у позы.
Порядок наложения частей
Части спрайта (будь то постоянная часть или группа) накладываются друг на друга согласно порядку, в котором они определены:
# resources.yaml
---
characters:
mt:
poses:
front_1:
parts:
body: sprites/mt/mt_1_body.png # сначала будет выведено тело
~uniform: # затем форма
pioneer: sprites/mt/mt_1_pioneer.png # пионерская форма
dress: sprites/mt/mt_1_dress.png # платье
swimsuit: sprites/mt/mt_1_swim.png # купальник
~face: # затем лицо
normal: sprites/mt/mt_1_normal.png # нейтральное лицо
smile: sprites/mt/mt_1_smile.png # улыбка
sad: sprites/mt/mt_1_sad.png # грустное лицо
# ... остальные параметры
canvasSize
Тип: текстовый нод
Определяет размер канваса спрайта. Этот параметр нужен для использования параметра position
у частей спрайта, т.к. относительно значения этого параметра производится позиционирование изображений.
Значение должно состоять из двух целых чисел, разделённых пробелом, и представлять собой корректное разрешение:
# resources.yaml
---
characters:
mt:
poses:
front_1:
canvasSize: 900 1080 # 900x1080
# ... остальные параметры
positions
Тип: список
Определяет именованные положения спрайта относительно игровой сцены. Не стоит путать с параметром positions
у частей спрайта.
# resources.yaml
---
characters:
mt:
poses:
front_1:
positions:
center: 0 0 # центр
left: -0.5 0 # лево
right: 0.5 0 # право
# ... остальные параметры
Данный параметр, указанный внутри позы, позволяет задавать положения, действительные только для этой позы. Это может быть полезно, если у разных поз спрайта разные размеры изображений, и они должны использовать разные координаты.
Указанные внутри нода персонажа позиции будут переопределять одноимённые позиции выше по иерархии.
Также можно указать значение только для одной оси, прописав .
в качестве значения для второй:
# resources.yaml
---
characters:
mt:
poses:
front_1:
positions:
center: -0.5 . # изменена только X-координата
left: . -0.5 # изменена только Y-координата
# ... остальные параметры
Значение для недостающей координаты будет браться из позиций с таким же ID выше по иерархии, если же таких нет — будет выставлен 0.
Подробнее о положениях можно почитать здесь.
sizes
Тип: список
Определяет именованные размеры спрайта относительно игровой сцены. Синтаксис схож с positions
:
# resources.yaml
---
characters:
mt:
poses:
front_1:
sizes:
normal: 1 1
close: 2 .
# ... остальные параметры
Внутри каждого нода можно также прописать позиции — они будут использоваться, когда у спрайта будет указанный размер:
# resources.yaml
---
characters:
mt:
poses:
front_1:
positions:
center: 0 0 # это значение будет использоваться при любых других размерах
sizes:
normal: 1 1
close:
value: 2 .
positions: # позиции при размере close
center: 0 0.25 # это значение будет использоваться при размере close
# ... остальные параметры
Размер в таком случае указывается внутри нода value
.
На примере выше, когда у спрайта в сценарии будут прописаны size close
и at center
, в качестве координат для center
будет использоваться значение 0 0.25
, а не 0 0
.
Аналогично positions
, размеры, указанные внутри нода персонажа, будут переопределять одноимённые размеры выше по иерархии.
Подробнее о размерах можно почитать здесь.
spritecolor
Тип: список
Цвета для наложения на спрайт. Используются для более естественного отображения спрайтов на различных фонах (день, ночь и т.п.).
Значением может быть как цвет, заданный в colors
, так и HEX-код или RGB(A)-код.
# resources.yaml
---
characters:
mt:
poses:
front_1:
spritecolor:
tokyo_street_sunset: #FFF1ED
# ... остальные параметры
Подробнее о цветах спрайтов можно почитать здесь.
shortnames
Тип: список
Определяет короткие имена для поз и различных вариаций частей групп, которые можно использовать в сценарии.
Короткие имена прописываются так же, как прописываются позы и группы внутри сценария:
# resources.yaml
---
characters:
mt:
shortnames:
front_sd: front smile dress # или front face:smile uniform:dress
После определения коротого имени, его можно использовать внутри сценария:
show mt front_sd with dissolve
default
Тип: текстовый нод
Определяет позу и части групп, которые будут выводиться по умолчанию (если конкретные значения не указаны в команде сценария).
В качестве значения можно прописать короткое имя или позу и параметры групп:
# resources.yaml
---
characters:
mt:
default: front smile dress
# ... остальные параметры
Теперь, когда в сценарии будет прописано show mt
, по умолчанию будет спавнится вариация front smile dress
.
positions
Тип: список
Определяет позиции, которые могут использовать все позы спрайта. Любые позиции внутри конкретной позы будут переопределять данные позиции, если у них совпадают ID.
Синтаксис идентичен синтаксису positions внутри позы:
# resources.yaml
---
characters:
mt:
positions:
center: 0 0
left: -0.5 0
# ... остальные параметры
sizes
Тип: список
Определяет размеры, которые могут использовать все позы спрайта. Любые размеры внутри конкретной позы будут переопределять данные размеры, если у них совпадают ID.
# resources.yaml
---
characters:
mt:
sizes:
normal: 1 1
close: 2 .
far:
value: 0.7 0.7
positions:
center: 0 -0.25
# ... остальные параметры
spritecolor
Тип: список
Определяет оверлей-цвета спрайтов, которые могут использовать все позы спрайта. Любые цвета внутри конкретной позы будут переопределять данные цвета, если у них совпадают ID.
# resources.yaml
---
characters:
mt:
spritecolor:
tokyo_street_sunset: #FFF1ED
# ... остальные параметры
chibis
Тип: список
Тип принимаемых ассетов:
texture
— тип по умолчаниюsprite
Добавляет изображение для команды chibi
.
Синтаксис:
# resources.yaml
---
chibis:
chibi1: images/chibi1.png
chibi2: images/chibi2.png
collections
Тип: список
В данном ноде определяются элементы галереи — фоны, цг, музыка, концовки и сноски (доступны из меню "Помощь").
Все элементы, за исключением концовок, становятся доступны в галерее после того, как игрок увидит (услышит) их в игре. Концовки же открываются специальной командой в сценарии.
Нод может содержать следующие параметры, каждый из которых является списком:
bg
cg
endings
notes
tracks
Все элементы в игре выводятся в том порядке, в котором они указаны (сверху вниз).
bg / cg
Тип: список
Список фонов/цг для галереи. ID каждого нода в данном списке должен соответствовать существующему фону/цг — встроенному в игру или же определённого внутри resources.yaml
:
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg # определение фона bus_stop
cg:
d1_rena_sunset: cg/d1_rena_sunset.jpg # определение цг d1_rena_sunset
collections:
bg:
bus_stop: # добавление фона bus_stop в галерею
thumb: gallery/thumbs/bg/bus_stop_284x160.jpg # превью
cg:
d1_rena_sunset: # добавление цг d1_rena_sunset в галерею
thumb: gallery/thumbs/cg/d1_rena_sunset_284x160.jpg
# остальные параметры
Каждый нод может содержать следующие параметры:
name
— названиеthumb
— превьюvariations
— вариации
name
Тип: языковой нод
Название фона/цг. Выводится в меню при просмотре, если у фона/цг есть вариации.
Если не указан, будет использован ID фона/цг.
thumb
Тип: ассет
Типы принимаемых ассетов:
texture
— тип по умолчаниюsprite
Файл превью для галереи.
Предпочтительное разрешение: 284x160.
variatons
Тип: список
Вариации фона/цг. Содержит ноды с вариациями, каждый из которых может содержать параметр name
— название, которое будет отображаться в меню при просмотре:
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg # определение фона bus_stop
bus_stop_day: bg/bus_stop_day.jpg # определение фона bus_stop_day
cg:
d1_rena_sunset: cg/d1_rena_sunset.jpg # определение цг d1_rena_sunset
d1_rena_day: cg/d1_rena_day.jpg # определение цг d1_rena_day
collections:
bg:
bus_stop: # добавление фона bus_stop в галерею
name: "Автобусная остановка"
thumb: gallery/thumbs/bg/bus_stop_284x160.jpg # превью
variations: # вариации
bus_stop_day:
name: "Автобусная остановка, день"
cg:
d1_rena_sunset: # добавление цг d1_rena_sunset в галерею
name: "Рена"
thumb: gallery/thumbs/cg/d1_rena_sunset_284x160.jpg,
variations: # вариации
d1_rena_day:
name: "Рена, день"
# ... остальные параметры
Вариации не могут иметь вариаций.
Вариациям можно не задавать параметр thumb
, т.к. превью для них не используются.
endings
Тип: список
Список концовок, отображаемых в меню "Помощь".
Каждый нод внутри списка — языковой нод.
Поддерживают тэги разметки Rich Text.
# resources.yaml
---
collections:
endings:
himitsu_good_end: Химицу, хорошая концовка
himitsu_bad_end: Химицу, плохая концовка
kagome_good_end: # концовка с переводами на два языка
ru: Кагомэ, хорошая концовка
en: Kagome, good ending
# остальные параметры
Разблокировка той или иной концовки происходит при помощи команды внутри игрового сценария.
notes
Тип: список
Список сносок, отображаемых в меню "Помощь".
Внутри списка прописываются ID сносок:
# resources.yaml
---
notes: # определение сносок
note1: "Сноска #1"
note2: "Сноска #2"
note3: "Сноска #3"
collections:
notes: # сноски, которые должны отображаться в меню "Помощь"
- note1
- note2
- note3
tracks
Тип: список
Список треков, отображаемых в галерее.
ID каждого нода внутри списка должен соответствовать ID встроенного в игру музыкального трека или трека, прописанного в resources.yaml
.
Название трека указывается внутри нода:
# resources.yaml
---
sound:
echo_avenue_old: sound/music/echo_avenue_old.mp3 # определение трека
collections:
tracks:
echo_avenue_old: Echo Avenue [Old Version] # добавление трека в галерею
Если название не указано, будет выведен ID трека.
Использование встроенных ресурсов
Чтобы вывести в галерее какой-либо элемент, встроенный в игру, достаточно просто прописать его ID и ID необходимых вариаций. Название и превью нужно указывать только в том случае, если вы хотите их изменить.
# resources.yaml
---
collections:
# для всех этих элементов будут использованы значения по умолчанию, встроенные в игру
bg:
tokyo_street_day:
variations:
tokyo_street_night:
tokyo_street_sunset:
tracks:
a_painful_story:
ddd_take_two:
endings:
himitsu_bad: # Химицу, плохая
himitsu_good: # Химицу, хорошая
Обратите внимание, что после ID нода нужно ставить двоеточие, но не нужно указывать параметры.
colors
Тип: список
Определяет цвета, которые можно использовать внутри игрового сценария и в параметрах resources.yaml
, принимающих цвет в качестве значения.
Значением цвета может быть HEX-код или RGB(A)-код:
# resources.yaml
---
colors:
red_brown: "#a55e55" # HEX-код указывается в кавычках, т.к. иначе символ "#" будет расценён как начало комментария
aquamarine: (127, 255, 212) # rgb-код
pink_half_opacity: (255, 20, 147, 127) # rgba-код
Поддерживаемые форматы HEX-кодов:
- #RGB
- #RRGGBB
- #RGBA
- #RRGGBBAA
entryPoint
Тип: текстовый нод
Входная точка сценария.
В этом ноде прописывается ID сценария, который должен запускаться при нажатии "Новая игра". Значением должен быть ID существующего сценария (встроенного в игру или определённого в модификации).
Значение по умолчанию: day1
Пример:
# resources.yaml
---
scenarios:
scenario1: scenarios/scenario1.txt # определение сценария scenario1
entryPoint: scenario1 # scenario1 будет запускаться при начале новой игры
help
Тип: список
В этом ноде прописывается текст "Контактов" и "Титров" для меню "Помощь".
Может содержать следующие параметры:
credits
— титрыcontacts
— контакты
Оба параметра являются языковыми нодами и поддерживают тэги разметки Rich Text.
# resources.yaml
---
help:
contacts: "Текст для обратной связи"
credits: "Текст титров"
live2d_characters
Тип: список
В этом ноде определяются Live2D-спрайты персонажей.
Так же, как и в случае со статичными спрайтами, каждый спрайтовый нод может содержать следующие параметры:
poses
positions
sizes
spritecolor
shortnames
default
Все параметры, кроме poses
, идентичны параметрам статичных спрайтов, поэтому здесь будут рассмотрены только отличия.
Кроме того, Live2D спрайты также могут содержать параметр layers
с информацией об анимационных слоях — синтаксис этого параметра также будет рассмотрен.
layers
Тип: список
Внутри данного параметра прописываются названия анимационных слоёв и анимаций, которые они содержат.
Слои делятся на два типа:
- Основные
- Вспомогательные
Основные слои — это те слои, состояние которых игра запоминает. Эмоции, положения рук, ног, головы и прочее. То, что должно быть записано в файле сохранения, если спрайт на экране.
Вспомогательные — слои для одноразовых анимаций, которые проигрываются и затем возвращают спрайт в исходное состояние. Это могут быть различные кивки, подпрыжки, махания руками и прочее. Информация о состоянии таких слоёв не записывается в файлах сохранений.
Определение слоёв и анимаций происходит в редакторе Unity, этот процесс рассмотрен в отдельной статье. В этой же статье будет рассмотрен процесс определения слоёв и анимаций в файле ресурсов мода, чтобы их можно было использовать внутри сценария.
Рассмотрим процесс определения нескольких слоёв:
# resources.yaml
---
live2d_characters
saya:
layers:
emotions:
- normal
- smile
- sad
hands:
- hands1
- hands2
- hands3
~shake:
- head
Здесь определяются 3 слоя — emotions
, hands
и shake
. Первые два — основные слои, для эмоций и положения рук соответственно, последний — вспомогательный. Внутри нодов слоёв прописаны названия анимаций, которые этот слой содержит.
Для определения вспомогательного слоя нужно перед его именем поставить символ ~
.
poses
Тип: список
Так же, как и у статичных спрайтов, внутри данного нода прописываются различные позы и их параметры.
Каждая поза может содержать следующие параметры, синтаксис которых идентичен аналогичным параметрам поз статичных спрайтов:
positions
sizes
spritecolor
default
Также им доступны два новых параметра:
skins
layers
layers
внутри позы определяет слои и анимации, действительные только для этой позы (или перезаписывает их, если слой с таким же названием прописан для всего спрайта в целом).
skins
же — аналог parts статичных спрайтов, в нём прописываются пути Live2D-префабов спрайта.
skins
Тип: список
Тип принимаемых ассетов: prefab
Синтаксис достаточно прост, внутри нода прописываются пути к префабам Live2D моделей:
# resources.yaml
---
live2d_characters:
saya:
poses:
front:
skins:
school_unfiform: ~@[bundle]://characters/saya/front/school_uniform/model.prefab # путь к префабу внутри каталога
Краткая форма записи
Ноды poses
и skins
необязательно указывать явно, если вы не намереваетесь использовать какие-либо другие параметры.
Допустим, тот же пример с определением позы front
и скина school_uniform
можно записать так:
# resources.yaml
---
live2d_characters:
saya:
front:
school_unfiform: ~@[bundle]://characters/saya/front/school_uniform/model.prefab # путь к префабу внутри каталога
Если бы мы захотели указать какие-то позиции, размеры, слои анимации и прочее — необходимо было бы явно указывать названия нодов.
Допустим, мы определяем слои анимаций и несколько позиций для всего спрайта персонажа в целом:
# resources.yaml
---
live2d_characters:
saya:
layers:
emotions:
- normal
- smile
- sad
hands:
- hands1
- hands2
- hands3
positions:
center: 0 -0.25
poses:
front:
school_unfiform: ~@[bundle]://characters/saya/front/school_uniform/model.prefab # путь к префабу внутри каталога
Т.к. нод спрайта содержит не только позы, но и другие параметры, нам нужно явно указать название нода с позами. Внутри же нода позы front
никаких других параметров, кроме скинов, нет — поэтому названием нода skins
можно пренебречь. Если бы нужно было указать какие-то дополнительные параметры для позы front
, скины бы прописывались внутри нода skins
.
menu
Тип: список
Определяет элементы кастомизации главного меню.
Доступные параметры:
bg
logos
tracks
Каждому элементу внутри параметров присваивается ID — целое число, которое определяет порядок выбора элементов (чем меньше число — тем выше приоритет):
# resources.yaml
---
menu:
bg:
0:
# параметры
1:
# параметры
logos:
0:
# параметры
1:
# параметры
tracks:
0:
# параметры
1:
# параметры
Также у каждого элемента может быть задан параметр condition
, в котором прописывается условие, при котором данный элемент может быть выбран для отображения.
bg
Тип: список
Список фонов для главного меню.
Фон может задаваться одним из двух параметров:
asset
name
Первый используется для указания пути конкретного ассета, второй — для указания ID определённого в resources.yaml
или встроенного в игру фона.
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg # определение фона bus_stop
menu:
bg:
0:
asset: bg/menu_bg.jpg # подгрузка фона из папки bg
1:
name: bus_stop # подгрузка фона bus_stop
Параметр asset
принимает следующие типы:
texture
— тип по умолчаниюsprite
prefab
Также можно в ноде просто указать путь до ассета без указания других параметров, в таком случае это будет равносильно указанию параметра asset
:
# resources.yaml
---
bg:
bus_stop: bg/bus_stop.jpg # определение фона bus_stop
menu:
bg:
0: bg/menu_bg.jpg # подгрузка фона из папки bg
Эффекты постобработки
Помимо описанных выше параметров, нод также может принимать ещё несколько параметров:
particles
twirl
noise
blur
Все эти параметры — булевые переменные, т.е. их значением может быть либо true
, либо false
. Они отвечают за включение/отключение соответствующих эффектов пост-обработки фона в главном меню:
# resources.yaml
---
menu:
bg:
0:
name: house_mc_day
twirl: true
particles: true
blur: true
noise: true
По умолчанию значения всех параметров — true
.
Также можно задать overlay-цвет для фона при помощи параметра color
:
# resources.yaml
---
menu:
bg:
0: # пример дневной вариации фона из главного меню игры
name: house_mc_day
color: "#AC8E0E32"
logos
Тип: список
Список логотипов для главного меню.
Изображение логотипа задаётся при помощи параметра asset
:
# resources.yaml
---
menu:
logos:
0:
asset: images/menu_logo.png
Также значением asset
может быть default
— в таком случае игра будет использовать встроенный логотип LMR:
# resources.yaml
---
menu:
logos:
0:
asset: default # будет использован логотип Love, Money, Rock'n'Roll
Параметр asset
данного нода — своего рода исключение, которое помимо пути ассета принимает и значение default
.
Ещё одной особенностью параметра asset
является возможность указать разные ассеты под разные языки, аналогично синтаксису языковых нодов, только в качестве значения нужно писать путь к ассету:
# resources.yaml
---
menu:
logos:
0:
asset:
ru: images/menu_logo_ru.png
en: images/menu_logo_en.png
Аналогично bg
, можно указать только путь к ассету, игнорируя остальные параметры:
# resources.yaml
---
menu:
logos:
0: images/menu_logo.png
1: default
Положение и размер логотипа
Положение и размер логотипа настраиваются двумя параметрами:
position
size
Оба параметра принимают как и ID положения/размера, указанного в resources.yaml
, так и числовые значения:
# resources.yaml
---
sizes:
logo_normal: 0.8 0.8
positions:
logo_top: 0 0.25
menu:
logos:
0:
asset: images/menu_logo.png
position: 0 0.25
size: 0.8 0.8
1:
asset: images/menu_logo.png
position: logo_top
size: logo_normal
tracks
Тип: список
Фоновые треки для главного меню.
Аналогично нодам bg
, трек указывается либо через asset
, либо через name
. Также можно указать только путь к ассету:
# resources.yaml
---
sizes:
logo_normal: 0.8 0.8
positions:
logo_top: 0 0.25
menu:
tracks:
0:
asset: sound/menu_track.mp3
1:
name: summertime # трек, встроенный в игру
2: sound/menu_track.mp3 # аналогично ноду с "0"
Параметр asset
принимает только один вид ассетов — sound
.
Условия вывода
Каждый нод фона/лого/трека может иметь параметр condition
, который отвечает за условие выбора того или иного элемента.
Условие может содержать глобальные и persistent переменные, а также значения datetime:
# resources.yaml
---
menu:
bg: # пример вывода стандартных фонов главного меню в зависимости от времени суток
0:
name: house_mc_day
color: "#AC8E0E32"
condition: "datetime.hour >= 7 && datetime.hour < 16"
1:
name: house_mc_sunset
color: "#87173E2D"
condition: "datetime.hour >= 16 && datetime.hour < 22"
2:
name: house_mc_night
color: "#3A00BE3C"
condition: "datetime.hour >= 22 || datetime.hour < 7"
Значения глобальных переменных будут браться из continue-сохранения (которое загружается при нажатии "Продолжить" в главном меню).
Если такого нет, будут использованы значения по умолчанию.
Пустые значения
Если вы хотите не выводить вообще ничего, достаточно в качестве значения для параметра asset
указать null
:
# resources.yaml
---
menu:
bg:
0:
asset: null # также можно указать как 0: null
logos:
0:
asset: null
tracks:
0:
asset: null
narrators
Тип: список
Определяет имена персонажей, которые можно использовать в игровом сценарии.
Параметры:
name
— имя персонажа, языковой нод. Обязательный параметр.advColor
— цвет для режима adv, по умолчанию #4E322BFF.nvlColor
— цвет для режима nvl, по умолчанию #8D5E55FF.simpleAdv
— булевый параметр.
По умолчанию в режимеadv
цвет имени не изменяется — он всегда белый, изменяется только цвет полупрозрачной обводки вокруг имени — это сочетается не со всеми цветами, их нужно тщательно подбирать.
ПараметрsimpleAdv
позволяет отключить обводку и использовать обычный текст, цвет которого задаётся параметромadvColor
.
Еслиtrue
, то будет выводиться обычный цветной текст, без обводки.
Еслиfalse
, то будет выводиться белый текст с цветной обводкой.
Значение по умолчанию:false
.
Пример:
# resources.yaml
---
narrators:
hi:
name: "Химицу"
advColor: "#91483c"
nvlColor: "#EC7070"
simpleAdv: true
notes
Тип: список
В этом ноде определяются внутриигровые сноски.
Каждая сноска является языковым нодом и поддерживает тэги разметки Rich Text.
Пример:
# resources.yaml
---
notes:
note1: "Сноска #1"
note2:
ru: "Сноска #2"
en: "Note #2"
particles
Тип: список
Тип ассетов: prefab
Определяет внутриигровые партикли (различные частицы, типа лепестков сакуры).
Партикли можно загружать только из Unity-каталогов — ассет должен быть префабом с компонентом Particle System
.
# resources.yaml
---
catalogs:
bundle: catalogs/bundle/catalog.json # определение каталога "bundle"
particles:
snow: ~@bundle://particles/snow.prefab # определение партиклей "snow" из префаба внутри каталога "bundle"
positions
Тип: список
В этом ноде определяются различные положения на экране, которые могут использоваться внутри игры — чаще всего они используются для расположения спрайтов персонажей.
Координаты задаются при помощи двух осей: X и Y — горизонтальной и вертикальной соответственно.
Видимое пространство находится в диапазоне от -1
до 1
.
Абсолютный центр экрана — 0 0
.
# resources.yaml
---
# примеры некоторых стандартных позиций спрайтов персонажей в игре
positions:
center: 0 -0.59
left: -0.67 -0.59
right: 0.67 -0.59
scenarios
Тип: список
Тип принимаемых ассетов: text
В этом списке определяются игровые сценарии.
Каждый нод может принимать путь к ассету сценария, а также к различным локализациям сценария на разные языки.
# resources.yaml
---
scenarios:
day1: scenarios/day1.txt # определение сценария "day1"
day2:
asset: scenarios/day2.txt # определение сценария "day2"
en: scenarios/day2_en.csv # английская локализация для "day2"
Как видно из примера, в случаях, когда к сценарию нужно прописать локализацию, путь к исходному сценарию указывается в параметре asset
, а переводы — внутри параметров с соответствующим языковыми кодами.
Параметр common
внутри данного нода неприменим.
sizes
Тип: список
В этом ноде определяются различные размеры, которые можно использовать внутри сценария и в других параметрах, принимающих размеры.
В основном размеры используются для масштабирования спрайтов персонажей.
Размеры задаются двумя параметрами: шириной и высотой, разделёнными пробелом:
# resources.yaml
---
sizes:
normal: 1 1 # определение размера "normal"
Также каждый размер может содержать внутри себя список положений, которые будут использоваться спрайтом персонажа в игре, если у него будут совпадать название размера и название позиции:
# resources.yaml
---
positions:
center: 0 -0.59 # определение позиции "center"
sizes:
close:
value: 1.95 1.95 # размер указывается в параметре "value"
positions:
center: 0 -1.57 # переопределение положения "center" для размера "close"
# также вместо X-координаты можно прописать точку:
# center: . -1.57
# в таком случае значение X будет взято из исходного положения (0 в данном случае)
Значение размера указывается внутри параметра value
, а позиции — внутри списка positions
.
На примере выше мы определили размер close
, при котором спрайт персонажа становится почти в 2 раза больше. Т.к. размеры спрайта изменились, значение для положения center
необходимо немного подкорректировать, чтобы спрайт корректно отображался в игре. Для этого мы переопределили значение center
при размере close
, немного сместив его вниз.
В итоге спрайт в игре при размере close
и положении center
будет выглядеть так:
А не так:
spritecolor
Тип: список
В этом ноде определяются overlay-цвета для спрайтов персонажей.
Эти цвета нужны для более корректного отображения спрайтов на различных фонах — дневных, ночных, закатных и т.д.
Цвета определяются следующим образом:
# resources.yaml
---
spritecolor:
tokyo_street_night: "#E9F6FF"
tokyo_street_sunset: "#FFF1ED"
Значением цвета может быть также и ID цвета, определённого в ноде colors.
Название цвета может быть любым (при необходимости вы сможете выбрать нужный цвет в сценарии вручную), однако удобнее всего использовать в качестве названий ID конкретных фонов, т.к. игра автоматически меняет цвета спрайтам на цвет, соответствующий названию активного фона, когда происходит смена фонов.
Спрайт на ночном фоне без overlay-цвета.
Тот же спрайт, но уже с цветом.
sound
Тип: список
Тип принимаемых ассетов: sound
В этом списке определяются звуковые файлы, которые можно использовать в сценариях.
Поддерживаются все форматы, распознаваемые Unity:
- mp3
- ogg (Vorbis)
- wav
- aiff / aif
- mod
- it
- s3m
- xm
Чтобы звуковой файл распознался, он должен иметь корректное расширение.
Звуки определяются следующим образом:
# resources.yaml
---
sound:
echo_avenue_old: sound/echo_avenue_old.wav
into_the_uknown: sound/into_the_uknown.mp3
transitions
Тип: список
Список различных пресетов для переходов.
Переходы бывают нескольких видов:
background
— переходы фоновcharacter
— переходы спрайтов персонажейscreen
— переходы всего экранаpattern
— подвид переходов фонов
В backgroud
, character
и screen
прописываются пресеты переходов, аналогично тому, как они прописываются в файле сценария:
# resources.yaml
---
transitions:
background:
dissolve2sec: dissolve 2 # dissolve длительностью в 2 секунды
character:
crossfade2sec: crossfade 2 2 # crossfade с fadeOut = 2 секундам и fadeIn = 2 секундам
fade212: fade 2 1 2 # fade с fadeIn = 1, hold = 1 и fadeOut = 2
screen:
fadeRed: fade color:#FF0000 # fade с красным цветом
hpunch2: hpunch 2 3 10 0 true # горизонтальный punch с duration = 2, strength = 3, vibrato = 10, randomness = 0 и fadeOut = true
В pattern
же прописываются ассеты изображений для переходов фонов типа pattern
:
# resources.yaml
---
transitions:
pattern:
chainsaw_pattern: images/patterns/chainsaw_pattern.jpg # определение изображения паттерна chainsaw_pattern
background:
chainsaw_pattern: pattern chainsaw_pattern 1.5 # определение перехода chainsaw_pattern длительностью в 1.5 секунды с использованием определенного выше изображения паттерна
///
Со списком доступных переходов и их параметрами можно ознакомиться здесь.
variables
Тип: список
В этом ноде определяются глобальные переменные мода, т.е., переменные, доступные во всех сценариях мода, и значения которых сохраняются при переходах между сценариями.
Переменные определяются следующим образом:
# resources.yaml
---
variables:
himitsu_points: 0 # определение переменной himitsu_points со значением "0" по умолчанию
day1_choice_made: false # переменная day1_choice_made со значением "false" по умолчанию
Значения глобальных переменных могут содержать числа, текст, булевые значения (true/false), а также различные алгебраические операции.
Значения определяемых глобальных переменных не могут содержать в себе другие переменные.
Мод-пример
Вы можете скачать небольшой мод-пример, который демонстрирует базовую часть описанных в данной документации возможностей.
Мод доступен в Steam Workshop, а также здесь.
Если вы установили мод через мастерскую, он будет расположен в папке steamapps\workshop\content\615530\3020524921.
Запуск модов
Моды запускаются из отдельной опции в игре:
В левом меню располагается список доступных модов. У каждого мода слева от названия находится иконка, обозначающая тип установленного мода:
Мод из мастерской | Мод из .scenario-архива | Мод внутри подпапки |
В правом верхнем углу окна располагаются фильтры, которые позволяют включать/отключать вывод в меню тех или иных типов модов.
В правом меню расположена обложка мода, его описание и кнопка активации.
В самом низу — кнопка обновления списка установленных модов (в классическом интерфейсе она находится сверху — первая кнопка слева от фильтров).
Активация мода
При активации мода, игра начнёт сохранять всю информацию о прогрессе (сейвы, открытые предметы галереи, прочитанные строки) отдельно от основной игры, в подпапках, которые соответствуют названию файла/подпапки мода (в случае с мастерской - его ID).
Чтобы применить любые изменения, сделанные в resources.yaml
, когда игра запущена и мод активирован, вам нужно будет деактивировать, а затем снова активировать мод — это правило распространяется и на любые изменения в каталогах и бандлах.
Локальный сервер
Для подгрузки внешних ресурсов игра использует локальный сервер, который по умолчанию запускается на порте 24463
при открытии модселектора.
Если указанный порт занят, при попытке открыть модселектор будет выведено окно с ошибкой:
Вы можете либо освободить указанный порт, закрыв программу, которая его использует, либо указать другой порт при помощи опции --local-port номер_порта
при запуске игры.
Готовый проект Unity
Для создания каталогов и импорта/экспорта Live2D-моделей вы можете скачать проект для Unity 2022.3.6f1, в котором установлены все необходимые плагины и произведены все нужные настройки.
Скачать можно здесь.
Плагины
- Addressables v1.21.15 (доступен через менеджер пакетов Unity)
- Live2D Cubism SDK for Unity v4-r7
- CubismPoser v1.0.1
Создание каталогов
Каталоги нужны для подгрузки каких-либо ассетов Unity из бандлов.
В этой статье будет рассмотрен процесс создания бандлов и каталога для них.
О том, как добавить созданный каталог в ресурсы игры, написано здесь.
Требования
У вас должны быть хотя бы минимальные знания по работе с редактором Unity и представление об ассет-бандлах.
Для продолжения вам понадобится редактор Unity 2022.3.6 с пакетом Addressables 1.21.15, который можно установить через менеджер пакетов внутри редактора.
Работоспособность каталогов в LMR не гарантируется при использовании других версий редактора/пакета Addressables.
Платформа сборки
Каталоги собираются под текущую активную плафторму в редакторе Unity. Её можно узнать, нажав на File -> Build Settings в меню редактора Unity или нажав Ctrl + Shift + B.
Если вы хотите, чтобы ассеты из каталогов работали на нескольких платформах (Windows, Android, Linux и т.п.) — вам нужно собирать их отдельно под каждую платформу.
Настройка Addressables
Вы можете скачать готовый проект с необходимыми настройками.
После установки редактора и пакета, откройте окно редактирования групп Addressables:
Windows -> Asset Managment -> Addressables -> Groups
Если вы открываете это окно в первый раз, у вас появится сообщение о необходимости создать настройки Addressables. Нажмите Create Addressables Settings.
Это сообщение появляется только при первом запуске
После того, как завершится создание настроек, вы увидите следующее окно:
Внутри этого окна можно создавать различные группы ассетов, из которых собираются бандлы, информация о которых после сборки будет добавлена в .json-файл каталога.
Прежде, чем вы начнёте создавать группы ассетов, необходимо изменить некоторые настройки, чтобы каталог корректно подгружался в LMR.
AddressableAssetSettings
При помощи проводника проекта (по умолчанию располагается в самом низу окна редактора), найдите ассет AddressableAssetSettings, полный путь которого:Assets/AddressableAssetsData/AddressableAssetSettings.asset
Кликните на него — в правой части окна редактора появится Inspector с настройками:
Для начала нам необходимо изменить настройки профиля по умолчанию, для этого кликните на Manage Profiles во вкладке Profiles, появится следующее окно:
Здесь нам нужно поменять настройки Remote. Нажмите на выпадающий список напротив и выберите в нём Custom.
Измените значение Remote.BuildPath на следующую строчку:ServerData/[BuildTarget]
Затем измените значение Remote.LoadPath:{LMR_MOD_ROOT}
Должно получиться так:
Закройте окно. Далее возвращаемся обратно к окну инспектора, и включаем чекбокс Build Remote Catalog во вкладке Catalog:
Убедитесь, что в выпадающем списке Build & Load Paths выбрано значение Remote с настройками, что мы указывали в профиле. У Build Path вместо [BuildTarget]
будет указана ваша платформа — это нормально.
В этой же вкладке включаем чекбокс Only update catalogs manually:
Последняя настройка, которую нам нужно изменить у данного ассета — это Strip Unity Version from AssetBundles, которая находится на вкладке Build — её необходимо включить:
Шаблоны групп
Далее нам необходимо изменить настройки по умолчанию для создаваемых групп. Они хранятся в файле Assets\AddressableAssetsData\AssetGroupTemplates\Packed Assets.asset
.
Находим этот файл, кликаем по нему и видим следующее:
Здесь нас интересуют следующие настройки:
- Build & Load Paths
Необходимо в списке выбрать Remote, чтобы использовались пути, которые мы указали в настройках ассета Addressables. - Use Assets Bundle Cache
Эту настройку необходимо выключить. Значение Build & Load Paths может сброситься на Local или <custom> — в таком случае поменяйте обратно на Remote. - Assets Bundle CRC
Эту настройку также необходимо отключить. Нажмите на выпадающий список и выберите там Disabled. - Bundle Naming Mode
Настройки нейминга бандлов. Рекомендуется выставить Append Hash To Filename. - Prevent Updates (вкладка Content Update Restriction)
Включите данный чекбокс.
В итоге, после изменения настроек, шаблон будет выглядеть так:
Далее вернёмся к окну Addressables Groups. В нём сейчас всего две группы: Built In Data и Default Local Group (Default):
Нажмите на Built In Data и отключите оба чекбокса в инспекторе:
Создание групп
Как было сказано ранее, внутри окна Addressables Groups создаются различные группы ассетов — из этих групп после сборки будут созданы бандлы. Каждая группа — отдельный бандл, в котором хранятся ассеты (зависит от режима сборки, о нём будет далее).
Чтобы создать группу, нажмите правкой кнопкой мыши по свободному месту в окне и выберите Create New Group -> Packed Assets. По умолчанию название будет Packed Assets, но вы можете изменить его, кликнув правой кнопкой мыши по группе и выбрав соответствующий пункт в меню. Названия групп не играют важной роли и могут быть любыми.
Удаление группы Default Local Group (Default)
После создания новой группы, удалите группу Default Local Group (Default), либо измените её настройки в соответствии с настройками шаблона Packed Assets. Если вы удалите группу, то следующая за ней группа станет группой по умолчанию.
Режим сборки ассетов
Этот параметр называется Bundle Mode, его можно найти в окне инспектора, кликнув по любой группе:
Он определяет, каким образом ассеты внутри группы будут собираться в бандл.
Pack Together — все ассеты из группы будут упакованы в один бандл, и, соответственно, в игре будут загружаться одновременно, даже если используется только один ассет из группы. Этот режим рекомендуется ставить, если в группе находятся ассеты от какого-то одного объекта - вроде анимированного фона и частей, из которых он состоит.
Pack Separately — для каждого ассета в группе будет создан свой одноимённый бандл, и каждый ассет будет загружаться в игре отдельно, без загрузки остальных ассетов из группы. Этот режим подходит для наборов статичных фонов, текстур и различных звуков. В общем, для всего, что не предполагается загружать одновременно.
Pack Together By Label — не используется в модах.
Значения для этого параметра вы должны выбирать сами, исходя из ассетов внутри вашей группы и их назначения — это исключительно вопрос оптимизации.
Если вы добавите в группу папку — все ассеты внутри неё будут загружаться в игре одновременно, даже если у группы стоит Pack Separately. По сути, папка - это группа внутри группы.
Добавление ассетов в группу
Чтобы добавить какой-либо ассет в группу, нужно перетащить его в необходимую группу внутри окна.
Также вы можете нажать на ассет и в окне инспектора включить чекбокс Addressable — в таком случае ассет будет добавлен в группу по умолчанию (вы можете перетащить его оттуда в любую группу).
Нейминг ассетов
После добавления ассета в группу, ему будет присвоено имя, соответствующее его пути внутри проекта. Такое имя называется адресом ассета (или его ключом) — именно на это имя вы будете ссылаться для загрузки ассета внутри файла ресурсов мода — resources.yaml.
Чтобы изменить имя, кликните по ассету в группе правой кнопкой мыши и выберите Change Address:
Ключи чувствительны к регистру.
Сборка каталога
После того, как вы создали все необходимые группы и добавили в них ассеты, вам нужно собрать бандлы и каталог для них. Делается это достаточно просто, для этого нужно в окне с группами нажать Build -> New Build -> Default Build Script:
Если это первая попытка сборки, то редактор спросит вас о необходимости включить новую систему отчётов — рекомендуем согласиться.
Если всё прошло хорошо, в консоли редактора появится следующее сообщение:
А также откроется окно с отчётом, если вы его включили:
После этого вам необходимо открыть корневую папку вашего проекта в любом файловом проводнике (не в редакторе) и найти там папку ServerData:
Внутри этой папки будут находиться папки с названием платформ, под которые вы собирали каталоги. В каждой такой папке будут лежать файлы бандлов, а также каталог и его хэш:
Переместите все эти файлы внутрь директории вашего мода.
После этого вы сможете указать путь к json-файлу каталога в resources.yaml и использовать ассеты из него внутри ресурсов вашего мода.
Если вы решите переименовать .json-файл каталога, вам нужно будет также изменить название .hash-файла.
Очистка кэша сборок
Перед каждой сборкой каталога рекомендуем очищать кэш предыдущих сборок. Это можно сделать из меню Build -> Clean Build Cache -> All внутри окна групп:
Импорт Live2D-моделей
В модах можно использовать кастомные Live2D-модели.
В этой статье будет рассмотрен процесс подготовки и импорта Live2D-модели в игру — о том, как непосредственно создавать Live2D-модели и работать с Live2D SDK, вы можете почитать в соответствующей официальной документации.
Требования
- Редактор Unity 2022.3.6;
- Live2D Cubism SDK для Unity (в проекте используется версия 4-r.7);
- Исходник Live2D-модели — файлы .moc3, model3.json, текстуры и опционально .motion3-файлы анимации;
- Умение работать с редактором и аниматором Unity;
Вы можете скачать готовый проект с необходимыми плагинами.
Введение
Для наглядности в данной статье будет описан процесс импорта модели в игру на примере спрайта второстепенного персонажа из старой демо-версии игры.
Вы можете скачать архив с исходниками по этой ссылке.
Ссылка на архив с финальным результатом расположена в конце статьи.
Импорт модели в Unity
Чтобы импортировать модель в Unity-проект, достаточно поместить её исходники внутрь папки Assets (или в любую её подпапку) — Live2D SDK импортирует модель и сгенерирует для неё префаб, а также контроллер анимации.
Распакуйте содержимое архива с исходниками спрайта в папку Assets вашего проекта. После того, как Live2D SDK закончит процесс импорта (он запустится автоматически при открытии окна редактора) — внутри папки с исходниками появится префаб, а также несколько вспомогательных ассетов:
Для всех .motion3-файлов внутри папки anim также были сгенерированы анимационные файлы, поддерживаемые Unity:
Откройте файл Kyo.prefab в редакторе — вы увидите импортированную модель:
Справа в окне Inspector будут отображаться настройки различных компонентов Live2D SDK, включая анимируемые параметры нашей модели (компонент Cubism Parameters Inspector):
Если модель не отображается после открытия префаба, попробуйте нажать кнопку Reset внутри Cubism Parameters Inspector (или просто измените значение какого-либо параметра). Также возможно, что модель просто не в фокусе камеры - нажмите F, чтобы сфокусировать камеру.
Если же модель отображается некорректно — попробуйте в компоненте Cubism Render Controller во вкладке Sorting выставить параметр Mode в Back To Front Order.
Первое, что нужно сделать — прицепить сгенерированный контроллер анимации к компоненту Animator — просто перетащите его в соответствующие поле:
Сохраните изменения (если у вас отключено автосохранение) и закройте префаб.
Удаление исходников
Очень важно после успешного импорта удалить исходники из проекта. На это есть две причины:
- Вы можете случайно положить исходники модели в бандл;
- По умолчанию каталог с бандлами не соберётся, если внутри будут неподдерживаемые Unity файлы;
Удалите все .moc3, .model3.json и .motion3 файлы из проекта после завершения процесса импорта модели. НЕ удаляйте текстуры — они используются в префабе.
Анимации
Откройте любую сцену в редакторе и перетащите на неё префаб импортированной модели:
Выберите модель в иерархии сцены, затем откройте окно Animator (Window -> Animation -> Animator).
Вы увидите стандартный шаблон контроллера с базовым слоем:
У нашей модели есть заранее заготовленные анимации переходов между положениями рук и ног, однако нет самих анимаций конечных положений, которые будут проигрываться, когда модель находится в idle-состоянии (т.е. не меняет положение рук или ног).
Мы можем сделать анимации вручную — создадим их для рук.
Переименуйте слой Base Layer в Hands (нужно кликнуть на название слоя), нажмите на шестерёнку справа и убедитесь, что параметр Weight у слоя равен единице:
При создании новых слоёв убедитесь, что значение Weight не равно нулю, иначе анимации на слое никак не будут воздействовать на модель в игре.
Полоса под названием слоя также отображает значение этого параметра — если она серая — значит, что значение равно нулю.
Затем создайте на нём новый стейт и назовите его hands1:
Т.к. это единственный стейт на слое, он будет проигрываться по умолчанию при появлении модели на сцене. Создайте второй стейт под второе положение рук — hands2:
У нас есть два стейта под два положения рук — замечательно! Пока что, правда, они ничего не делают, т.к. у них нет анимаций — мы сделаем их чуть позже.
Откройте папку anim в папке с моделью и найдите там две сгенерированные анимации:
- hands1-2
- hands2-1
Это переходные анимации для различных положений рук. Первая — переход из 1 положения во 2, вторая — из 2 в 1. Перетащите оба этих файла на слой Hands, к созданным ранее стейтам:
В отличии от созданных вручную стейтов hands1/hands2, этим стейтам автоматически присвоились анимации. Вы можете увидеть их в инспекторе, в параметре Motion, кликнув по стейту:
Теперь мы можем сделать переходы между 2-мя положениями рук, которые будут проигрываться, когда модель меняет hands1 на hands2 и наоборот.
Это можно сделать двумя способами:
- Используя традиционную систему триггеров и переходов Unity;
- Используя упрощённую систему переходов, реализованную в LMR;
В этой статье будут рассмотрены оба способа, вы можете использовать тот, что кажется вам наиболее удобным.
Переходы
Реализация переходов при помощи триггеров
Создайте в параметрах аниматора триггеры, названия которых совпадают с названием стейтов основных положений рук (в данном случае — hands1 и hands2):
Далее создайте переходы между положениями рук, которые будут активироваться при помощи триггеров:
Переход из hands1 в hands2 активирует триггер hands2, из hands2 в hands1 — триггер hands1. Оба перехода происходят через стейты с анимациями смены положения рук.
Также снимите чекбокс Has Exit Time у переходов из основных стейтов и поставьте Transition Duration 0:
Предупреждение выводится, т.к. у основных стейтов пока что нет анимаций — мы скоро сделаем их.
У переходов на основные стейты поставьте значение Exit Time на 1 и Transition Duration на 0:
После проигрывания анимаций переходов, аниматор сразу перейдёт на основной стейт без задержек.
Реализация переходов при помощи упрощённой системы
Этот способ был придуман, когда мы столкнулись с неудобствами первого. При большом количестве анимаций и переходов между ними, схема может превратиться во что-то подобное:
Так выглядит слой Head у спрайта himitsu_front
С этим не очень удобно работать и очень легко запутаться откуда и куда идёт тот или иной переход, поэтому был разработан альтернативный вариант.
Суть заключается в том, что стейты, которые должны проигрываться при переходах между основными стейтами (положениями рук hands1 и hands2 в нашем случае), называются определённым образом, используя достаточно простой синтаксис:
стейт_из_которого_переход | стейт_в_который_переход
Т.е. два стейта — "Стейт A" — из которого нужно перейти — и "Стейт Б" — в который нужно перейти, разделяются символом |
.
Создадим такие переходы для наших положений рук. Сейчас у нас есть следующее:
Переименуйте hands1-2 в hands1 | hands2, а hands2-1 в hands2 | hands1:
И всё! Никаких триггеров, стрелочек переходов и прочих настроек. Игра автоматически будет проигрывать наши анимации при смене положений рук. Данный способ очень удобен, если у вас есть анимации переходов между различными состояниями модели и у вас нет необходимости делать сложные системы переходов при помощи аниматора Unity.
Автоматически переходы
Если мы не создадим вообще никаких стейтов для переходов, игра автоматически будет пытаться перейти из одной анимации в другую за фиксированное время. Подобная система не подходит для чего-то сложного (например, такие переходы для конечностей будут выглядеть не очень), но для чего-то простого, вроде эмоций, вполне подходит.
Создание анимаций
В идеале, все анимации для вашей модели вы должны делать в редакторе Live2D, а затем импортировать в Unity. Однако, если по какой-то причине вы решили этого не делать, существует также возможность создавать анимации прямо в редакторе Unity.
Средствами Live2D SDK для Unity создавать анимации крайне проблематично, т.к. окно записи анимаций не будет реагировать на изменение параметров модели (и сама модель не будет реагировать на проигрывание анимаций вне контроллера, который работает только в Play-моде), поэтому для этих целей нами был написан специальный плагин, позволяющий анимировать Live2D-модели внутри Unity.
Скачайте и импортируйте его в проект.
Если вы скачали готовый проект по ссылке в начале статьи, плагин можно не качать — он идёт в комплекте.
Выберите модель на иерархии сцены и добавьте к ней компонент CubismPoser. После этого компонент Cubism Parameters Inspector должен исчезнуть, а вместо него, в самом низу, появится новый компонент с теми же параметрами:
Анимации для положений рук
Сделаем анимации для основных положений рук - hands1 и hands2.
Выберите модель на иерархии сцены, затем откройте окно Animation (Window -> Animation -> Animation, или Ctrl + 6). Вы увидите окно, в котором будут ключи анимаций-переходов:
Мы можем посмотреть значения параметров в начале и в конце анимации.
У первого положения рук (hands1) параметр Ruki1 должен быть равен 0, у второго (hands2) — 1.
Кликните на выпадающий список в левом верхнем углу окна и создайте новый анимационный файл, нажав на Create New Clip...
Назовите его hands1 и сохраните в папку с остальными анимациями.
Убедитесь, что на таймлайне установлен 0 кадр:
Далее включите режим записи, выберите в компоненте CubismPoser параметр Ruki1 и установите его значение на 0:
Затем нажмите кнопку Create Keyframes for Selected (активна только в режиме записи).
На таймлайне должен появится ключ со значением нашего параметра:
Поздравляю - вы только что создали анимацию для Live2D-модели в Unity (пусть она и состоит только из одного кадра).
Сделайте то же самое для hands2, установив значение Ruki1 на 1:
Анимации готовы. Теперь осталось только добавить их к соответствующим стейтам в аниматоре (по идее, они должны добавиться сами, если названия стейтов и анимаций совпадают):
Готово. Вы сделали полностью функционирующие положения рук для модели, а также переходы между ними.
В исходниках модели также лежат анимации переходов ног — вы можете попрактиковаться на них, процесс абсолютно идентичен.
Эмоции
В архиве с исходниками нет никакой анимации эмоций, но вы можете попробовать создать свои. Функциональность модели ограничен (всё же, это спрайт из старой демо-версии игры), но у неё есть несколько параметров, отвечающих за эмоции.
При создании анимации эмоций очень важно создавать ключи для всех параметров, отвечающих за эмоции — иначе при переходах какие-то значения, которые не используются в конкретной анимации, могут не изменяться после предыдущей анимации.
Сделаем несколько эмоций для нашего спрайта: создайте в аниматоре новый слой Emotions и переместите его в самый верх:
Далее создадим несколько анимационных файлов:
normal
Обычное (стандартное) выражение лица персонажа, которое будет активно по умолчанию. Выделяем все необходимые параметры, не меняя их значений, и создаём новый файл анимации с ключами:
sad
grin
Для всех созданных анимаций в аниматоре были автоматически проставлены одноимённые стейты — по умолчанию они создаются на самом верхнем (первом) слое:
Нам не нужно ничего менять — для смены эмоций в игре достаточно автоматических переходов.
Дыхание и моргание
Дыхание и моргание реализуются при помощи стандартных компонентов Live2D SDK:
- Cubism Harmonic Motion Controller
- Cubism Harmonic Motion Paramater
- Cubism Eye Blink Controller
- Cubism Eye Blink Input
- Cubism Auto Eye Blink Input
Подробнее о настройках вы можете прочитать в официальной документации. Далее будет рассмотрен процесс настройки этих компонентов с общими параметрами, которые используют модели в игре.
Все настройки должны проходить в префабе модели — чтобы изменения сохранились не только на сцене.
Дыхание
Добавим нашей модели анимацию дыхания.
Откройте префаб и добавьте к нему компонент Cubism Harmonic Motion Controller, значение Blend Mode установите в Override:
Далее в иерархии модели внутри Parameters найдите объект Dihanie и добавьте к нему компонент Cubism Harmonic Motion Parameter:
Установите параметры следующим образом:
Моргание
Добавьте к префабу модели два компонента: Cubism Eye Blink Controller и Cubism Auto Eye Blink Input со следующими параметрами:
Далее в иерархии модели внутри Parameters найдите объект GLAZA_otkr и добавьте к нему компонент Cubism Eye Blink Parameter:
Сохраните изменения и закройте префаб.
Проверка
Вернитесь на сцену, расположите модель перед камерой, задав ей подходящий размер.
Если вы скачали готовый проект, то вы можете воспользоваться следующими параметрами:
Включите Play-мод. Если всё сделано верно, модель должна дышать и моргать:
Финальный результат
Архив с моделью, анимациями и двумя контроллерами (kyo.controller — с триггерами, kyo_simple.controller — без) можно скачать здесь.
Экспорт в игру
- Соберите каталог с моделью и всеми необходимыми ассетами.
- Добавьте каталог в ресурсы мода.
- Добавьте в ресурсы мода спрайт персонажа, вписав модель, необходимые слои и стейты.
Если вы всё сделали верно, модель и анимации будут корректно отображаться в игре:
Исходники Live2D-спрайтов для Unity
Описание
Архив содержит префабы всех игровых спрайтов с текстурами, контроллерами, анимациями и несколькими небольшими вспомогательными скриптами для условий переходов.
Исходники можно использовать для редактирования имеющихся в игре спрайтов, а также для создания новых анимаций из имеющихся у моделей параметров.
Ссылка
Вы можете скачать архив с исходниками, кликнув по этой ссылке. Распакуйте содержимое архива внутрь папки Assets
вашего проекта.
Содержимое
Внутри папки models
находятся подпапки, содержащие префабы и текстуры для различных поз и скинов спрайтов.
Внутри папки anims
находятся подпапки, содержащие контроллеры и анимации.
Папка scripts
содержит вспомогательные скрипты, используемые в контроллерах. Они нужны для изменения параметров контроллера, которые используются в условиях различных переходов.
Переводы сценариев
Строки в сценарии можно переводить на другие языки.
По умолчанию, если у сценария нет перевода, для всех языков будет выводиться текст, прописанный в исходном сценарии.
Подготовка сценария
Первое, что нужно сделать — это подготовить сценарий для перевода.
Следующие команды сценария поддерживают переводы:
Для каждой такой команды, текст которой нужно перевести, необходимо придумать уникальный идентификатор. Он прописывается в самом начале команды через двоеточие:
# пример сценария с локализируемыми командами
text1: "Эти падающие лепестки сакуры..."
menu
{
text2: "Опция 1"
{
"..."
}
text3: "Опция 2"
{
"..."
}
}
Здесь text1
, text2
и text3
— идентификаторы строк для переводов. Они необязательно должны называться именно так, можно написать любое название (однако оно подчиняется общим правилам составления имён — только латинские буквы, цифры и нижнее подчёркивание), но оно обязательно должно начинаться с буквы.
Файл перевода
Переводы для сценариев хранятся в .csv-файлах.
Рассмотрим перевод первого дня игрового сценария:
Как можно увидеть из примера — в первом столбце прописываются идентификаторы, во втором — строки (включая кавычки), которые необходимо заменить в игре — со всеми тэгами.
Чтобы прописать в строке кавычку (т.е., чтобы она отображалась непосредственно в игре), нужно перед ней поставить символ \
— обратный слэш:
По сути, строки из файла перевода просто заменяют текстовую часть строки в игровом сценарии — поэтому синтаксис у них должен совпадать. В переводах также можно использовать переменные.
После создания файла перевода, вы можете прописать его в resources.yaml.
Разделитель
Можно использовать любой разделитель, поддерживаемый .csv-форматом. Однако мы рекомендуем использовать символ ;
.
Примеры
Вы можете посмотреть, как устроены игровые сценарии и их переводы на этой странице.
Загрузка мода в Steam Workshop
Для загрузки вашего мода в Steam Workshop вы можете воспользоваться специальной утилитой, которая расположена в папке Love, Money, Rock'n'Roll_Data\workshop_uploader
.
Утилита доступна под следующие платформы:
- Windows (x86/x64)
- Linux (x64)
- macOS (Universal x64)
Графический интерфейс
Или же lmr-workshop-gui(.exe)
.
При запуске программы вы увидите меню с двумя кнопками:
Первая создаёт новый мод в Workshop, вторая обновляет существующий.
В обоих случаях вы увидите одинаковое окно с различными параметрами:
При обновлении существующего мода, все параметры, кроме ID и директории, будут по умолчанию отключены, т.к. чаще всего обновляется только содержимое мода, а не сама страница в Workshop. Вы можете включить эти поля, кликнув по соответствующему лейблу:
Это также работает и при создании мода — вы можете отключить ненужные поля.
Чтобы вернуться обратно в меню, кликните по заголовку страницы:
Процесс загрузки/обновления мода
Перед тем, как загрузить или обновить мод, вам нужно запустить клиент Steam и залогиниться в нём с того аккаунта, с которого вы хотите взаимодействовать с мастерской.
Если клиент Steam не запущен, вы не залогинены или нет соединения с интернетом, появится окно с ошибкой:
После успешной загрузки/обновления будет выведен ID вашего мода, а также ссылка на него:
Если вы создаете мод, то по умолчанию после загрузки он будет доступен только с вашего аккаунта. Это сделано для того, чтобы у вас была возможность проверить корректность описания и работоспособность мода непосредственно при установке через мастерскую перед тем, как вы сделаете вашу модификацию общедоступной.
Если вы не принимали со своего аккаунта соглашение подписчика Steam, вы не сможете изменить видимость страницы мода, пока не примите соглашение.
В таком случае после загрузки мода также дополнительно появится сообщение со ссылкой на принятие соглашения.
Вы можете изменить настройки видимости вашего мода на странице в мастерской либо через утилиту, обновив мод с указанием настройки видимости.
Консольный интерфейс
Если вы предпочитаете взаимодействовать с консолью, то вы можете воспользоваться утилитой lmr-workshop(.exe)
.
Список доступных параметров:
-mode|--mode Operating mode. Possible values: create, update
-id|--id The ID of the Steam Workshop item. Used with update mode and --open-item-page.
-ttl|--title Sets a new title for an item
-dsc|--description Sets a new description for an item
-lng|--language Sets the language of the title and description that will be set in this item update
-vsb|--visibility Sets the visibility of an item. 0 - public, 1 - friends only, 2 - private, 3 -
unlisted
-ct|--content Sets the folder that will be stored as the content for an item
-pw|--preview Sets the primary preview image for the item
-cn|--change-note Change note for an item upload
-joutput|--json-output Returns all output in JSON
-owa|--open-workshop-agreement Opens Steam Workshop Legal Agreement in the Steam Client App
-oip|--open-item-page Opens item workshop page in the Steam Client App
-?|-h|--help Show help information.
Запуск под Linux
Для работы программы на Linux может потребоваться файл steamclient.so
, который является частью SteamCMD. Без этого файла, при попытке загрузить изменения, вы получите сообщение о незапущенном клиенте Steam.
После установки SteamCMD, найдите указанный файл и поместите его в папку home/%имя_юзера%/.steam/sdk64
(или по тому пути, который требует программа на вашей системе).
Вы также можете скачать необходимый файл отдельно.
Запуск под macOS
Если программа не запускается, ознакомьтесь с данной статьёй.
Миграция со старой системы модов
В игре, до релиза новой системы модов, была также и старая система, которая позволяла напрямую заменять конкретные ресурсы игры по их адресу при помощи бандлов.
Эта система была неидеальна и крайне неудобна (она не задумывалась для публичного релиза), однако нам известно, что при помощи данной системы было реализовано несколько относительно крупных модов.
Чтобы корректно интегрировать сценарии таких модов в новую систему, нужно будет провести несколько изменений.
Positions
Числовые положения спрайтов, прописывающиеся в сценарии при помощи ключевого параметра at
, были изменены. Теперь координаты рассчитываются относительно центра экрана, в значениях в диапазоне от -1
до 1
.
Чтобы получить корректное значение для новой системы из старых координат, нужно разделить значение X на 640
, а Y на 16.85
.
Т.е, если раньше было: show hi at 537 -6.68
То в новой системе оно будет выглядеть так (значения округлены):show hi at 0.84 -0.4
Sizes
Размеры тоже изменились. Нормальный (стандартный) размер спрайта теперь равен 1
.
Чтобы получить корректные значения, X и Y нужно разделить на 16.85
.
Было:show hi size 9 9
Стало (значения округлены):show hi size 0.53 0.53
Backdrop
Раньше, чтобы вывести backdrop-фон без текста, нужно было либо делать дополнительную пустую строку в XML-ассете, либо писать backdrop ""
.
В этом больше нет необходимости, текст у команды backdrop необязателен.
Строчки, вроде backdrop
или backdrop bg el
, в которых нет текста, теперь являются корректными.
Баги и обратная связь
Ниже приведён список багов, о которых известно на данный момент, но которые по тем или иным причинам пока что не были исправлены.
Если вы обнаружите баг, которого нет в этом списке, пожалуйста, сообщите нам о нём одним из следующих способов:
- VK
- Discord
- Почта support@lmr.su (обязательно укажите в теме "Баг-репорт, моды")
Также мы будем признательны за репорты об ошибках и неточностях в документации.
Известные баги
Crossfade и fade не работают для внешних звуковых файлов
Описание
Треки, загруженные из внешних звуковых файлов, не могут использовать параметры crossfade
и fadein
/fadeout
, если текущий и следующий трек — один и тот же файл (например, в случаях, когда трек должен зацикливаться с одним из вышеуказанных параметров).
Баг связан с особенностью загрузки внешних ассетов в Unity, мы работаем над устранением проблемы.
Временное решение
Треки можно поместить в бандл (каталог) — в таком случае все функции будут работать корректно.