Анимации двигают моба. А контроллер рендера решает, чем моб рисуется: какой моделью, какой текстурой и каким материалом. Ещё он умеет прятать части модели. В этом гайде наш Рубиновый голем получит три цвета самоцветов и корону, которую носит только иногда.
Контроллеры рендера находятся в пакете ресурсов. Как и анимации, они меняют только внешний вид моба.
Файлы
RP/
entity/
ruby_golem.entity.json
render_controllers/
ruby_golem.render_controllers.json
textures/
entity/
ruby_golem/
red.png
pink.png
dark.pngА он вообще нужен?
У многих мобов одна модель и один скин. Для них подойдёт ванильный контроллер controller.render.default. Он рисует геометрию, текстуру и материал, которые в клиентской сущности называются default, и никакой файл писать не нужно. Именно так сделано в гайде Ваш первый моб.
Свой контроллер рендера нужен, когда:
- у моба есть несколько текстур на выбор, например цвета или скины,
- моб меняет модель, как овца, которая теряет шерсть,
- части модели должны появляться или исчезать, например седло или броня,
- моба нужно окрасить в какой-то цвет.
Короткие имена берутся из клиентской сущности
Контроллер рендера никогда не использует пути к файлам. Он использует короткие имена, которые вы дали в клиентской сущности, с приставкой впереди:
| В клиентской сущности | В контроллере рендера |
|---|---|
"geometry": { "default": "geometry.wiki.ruby_golem" } | geometry.default |
"textures": { "red": "textures/entity/ruby_golem/red" } | texture.red |
"materials": { "default": "entity_alphatest" } | material.default |
То есть texture.red означает "текстура, которую я назвал red в клиентской сущности".
Шаг 1: самый простой контроллер
Файлы контроллеров рендера кладутся в папку render_controllers:
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.ruby_golem": {
"geometry": "geometry.default",
"materials": [{ "*": "material.default" }],
"textures": ["texture.red"]
}
}
}Три главные части:
| Поле | Что в нём |
|---|---|
geometry | Одна модель. Одно значение, а не список. |
materials | Список, который сопоставляет кости и материалы. * означает все кости. |
textures | Список текстур. Большинству мобов нужна только одна. |
Имя должно начинаться с controller.render.. Затем укажите его в клиентской сущности:
"render_controllers": ["controller.render.ruby_golem"]Шаг 2: три цвета самоцветов
Теперь самое интересное. Сначала перечислите все три текстуры в клиентской сущности:
"textures": {
"red": "textures/entity/ruby_golem/red",
"pink": "textures/entity/ruby_golem/pink",
"dark": "textures/entity/ruby_golem/dark"
}Потом поместите их в массив в контроллере рендера и выберите одну с помощью Molang:
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.ruby_golem": {
"arrays": {
"textures": {
"array.gem_colors": [
"texture.red",
"texture.pink",
"texture.dark"
]
}
},
"geometry": "geometry.default",
"materials": [{ "*": "material.default" }],
"textures": ["array.gem_colors[query.variant]"]
}
}
}array.gem_colors[query.variant] означает "возьми из списка элемент с номером query.variant". Счёт начинается с 0, поэтому вариант 0 - красный, 1 - розовый, а 2 - тёмный.
Откуда берётся query.variant?
Из пакета поведения. Компонент minecraft:variant хранит на мобе число, а query.variant его читает. Здесь каждый голем при появлении выбирает случайный цвет:
"component_groups": {
"wiki:color_red": { "minecraft:variant": { "value": 0 } },
"wiki:color_pink": { "minecraft:variant": { "value": 1 } },
"wiki:color_dark": { "minecraft:variant": { "value": 2 } }
},
"events": {
"minecraft:entity_spawned": {
"randomize": [
{ "weight": 2, "add": { "component_groups": ["wiki:color_red"] } },
{ "weight": 1, "add": { "component_groups": ["wiki:color_pink"] } },
{ "weight": 1, "add": { "component_groups": ["wiki:color_dark"] } }
]
}
}У красного вес 2, поэтому он выпадает вдвое чаще, чем каждый из остальных.
Выход за границы - не ошибка
Если число больше длины списка, счёт идёт по кругу: в списке из 3 элементов число 3 снова выбирает элемент 0. Отрицательные числа выбирают элемент 0. Поэтому неправильный вариант покажет не тот цвет, но игра не вылетит.
Массивы для моделей и материалов
arrays может содержать три вида списков. В каждом списке может быть только что-то одного вида:
| Ключ внутри arrays | Что хранит | Пример элемента |
|---|---|---|
textures | Текстуры | texture.red |
materials | Материалы | material.default |
geometries | Модели | geometry.default |
Массив нужен не всегда. Для простого выбора из двух вариантов подойдёт тернарный оператор Molang:
"geometry": "query.is_baby ? geometry.small : geometry.default"Шаг 3: прячем и показываем части
part_visibility включает и выключает кости. У нашего голема есть кость crown, которую он показывает, только когда приручён:
"part_visibility": [
{ "*": true },
{ "crown": "query.is_tamed" }
]- Каждая запись - это имя кости и значение.
trueили любое ненулевое значение показывает её,falseили 0 прячет. - Если спрятать кость, спрячутся и все её дочерние кости.
- Записи применяются по порядку, поэтому побеждают более поздние. Здесь сначала показывается всё, а потом корону настраивает запрос.
*работает как подстановочный знак:"gem_*"подходит кgem_left,gem_rightи так далее.
Список materials работает так же: сначала { "*": ... } для всего, а после него переопределяйте отдельные кости.
"materials": [
{ "*": "material.default" },
{ "core": "material.glow" }
]Чтобы это сработало, glow должно быть коротким именем в materials клиентской сущности и указывать на настоящий светящийся материал, например entity_emissive_alpha.
Цвета и эффекты
Контроллер рендера может менять и цвета. Все эти поля необязательные:
| Поле | Что делает |
|---|---|
color | Окрашивает моба. Нужен материал, который поддерживает окрашивание. |
overlay_color | Накладывает цвет поверх всего моба, a задаёт силу |
is_hurt_color | Вспышка, когда моб получает урон. В ванили она красная. |
on_fire_color | Оттенок, пока моб горит |
ignore_lighting | true рисует моба с полной яркостью, даже ночью |
uv_anim | Сдвигает текстуру со временем через offset и scale, для эффекта течения |
У каждого цвета есть r, g, b и a от 0 до 1, и каждый может быть Molang:
"overlay_color": {
"r": 1.0,
"g": 1.0,
"b": 1.0,
"a": "variable.is_shouting ? 0.5 : 0.0"
}Несколько контроллеров
render_controllers в клиентской сущности - это список. Каждый контроллер рисует моба один раз со своей моделью, поэтому их можно накладывать друг на друга. В ванили так сделаны слои вроде брони или светящихся глаз.
Ещё можно добавить условие, чтобы контроллер рисовал только иногда:
"render_controllers": [
"controller.render.ruby_golem",
{ "controller.render.ruby_golem_shine": "query.is_powered" }
]Если что-то не работает
| Что вы видите | Самая вероятная причина |
|---|---|
| Моб невидим | В имени контроллера рендера в клиентской сущности опечатка, или файл лежит не в render_controllers |
| Чёрно-фиолетовые клетки | Короткое имя текстуры или её путь неверные, или путь заканчивается на .png |
| Все големы красные | Пакет поведения не задаёт minecraft:variant, поэтому query.variant равен 0 |
| Спрятанная часть всё равно видна | Более поздняя запись part_visibility снова её включает, например * в самом конце |
| Окрашивание ничего не делает | Материал не поддерживает окрашивание. Попробуйте ванильный материал, сделанный для этого |
Больше помощи в разделе Когда что-то сломалось.
Что дальше
- Заставьте моба двигаться с помощью Анимаций сущностей.
- Проигрывайте звуки и частицы из анимаций с помощью Событий анимации.
- Рисуйте скины получше по гайду Пиксельные текстуры.