Привет всем! Увидел ресурс пак изменяющий модель Ифрита (Всполох, Blaze):
И подумал, а я тоже так хочу. Скачал этот пак, посмотрел внутрь, а потом ещё и посмотрел более подробно в сети.
И теперь хочу поделиться своими находками с вами! Погнали.
Что нужно знать до?
Что такое ресурс пак для Minecraft знают все, я думаю. Это могут быть модели, текстуры, шейдеры. Короче, какие-то дополнительные или альтернативные ресурсы. Есть ещё датапаки, но они созданы, чтобы вносить более глобальные изменения в то, как игра работает. Их используют, чтобы редактировать достижения, рецепты, биомы, дроп и т.д. Но в этот раз нас интересуют только модели и Optifine.
Если честно, то в этом паке была ещё папка со скриншотами, но они нам ни к чему там. Необязательно для создания своего пака брать чей-то, всё необходимое можно создать буквально по ходу дела. Я просто начал с этого для наглядности. Итак, разберём, что же тут у нас есть.
pack.mcmeta это JSON объект, который содержит описание и версию игры. Создать и открыть его можно обычным блокнотом, только следите, чтобы в имени файла не осталось всяких .txt!
{ «pack»: { «pack_format»: 6, «description»: «A Recource Pack by Someone» } } |
Цифра 6 для pack_format соответствует версиям 1.16.2 — 1.16.5. Для других версий:
- 4 для версий 1.13 – 1.14.4
- 5 для версий 1.15 – 1.16.1
- 6 для версий 1.16.2 – 1.16.5
- 7 для версии 1.17+
Описание (description) может быть практически любым. Не забывайте, что для JSON важно положение кавычек, запятых и скоб. Не оставляйте открытыми блоки. Если надо поставить именно кавычки, то используем ».
pack.png — изображение, которое игрок увидит в игре. В примере мы будем использовать png изображение 560х560.
Теперь более интересное. Папка assets. Именно тут и будут наши ресурсы. Чтобы не грузить лишней инфой, просто создайте такие папки: assetsminecraftoptifinecem. В последней и будут сохранены новые модели.
Формат моделей будет .jem и именно их мы сейчас будем создавать.
Модели тоже можно открыть блокнотом и там снова будет JSON код. Но руками это писать — дикое извращение. На помощь нам приходит достаточно удобное решение в виде Blockbench. Я его уже когда-то использовал для гайда по созданию нового моба на Forge.
Запускаем редактор и видим такое окошко:
Получаем пустой проект. Предлагаю изменить курочку, поэтому используем chicken в имени модели:
И теперь можно начинать творить 😊. Хотя, куда проще было бы редактировать существующие, чем делать с нуля, да? Для этого существует очень неплохой плагин CEM Template Loader.
И выбираем курицу запустив плагин из вкладки Filter:
Результат:
Окей, ноги странные, но это потому, что модель пока без текстуры. Добавляем текстуру (временно):
Но есть весомое НО. У моделей для optifine есть свои требования для имён частей тела. Курице нужны такие части:
# chicken head, body, right_leg, left_leg, right_wing, left_wing, bill, chin.
У нас всё совпало, это хорошо.
Список имён для других мобов.
Соблюдать имена обязательно для правильной работы модели. И для адекватной анимации.
Завершение и создание ресурс пака для Minecraft Optifine
Можно создавать практически любые модели, но в рамках возможностей редактора, конечно же. К примеру… сделать курицу размером с гиганта или переделать вообще всё полностью с нуля. Для результата главное чтобы совпадали имена групп (то, что с иконкой папки в редакторе). Я решил просто сделать курицу более курицей.
Теперь обсудим текстуру. Вы можете оставить так, но тогда модель будет искать текстуру в той же папке, что и она сама. Т.е. для использования своих текстур их можно просто закинуть в assetsminecraftoptifinecem. Но тогда ваша текстура не будет реагировать на текстурпаки. Нам это не нужно, так что удаляем текстуру из проекта и через File -> Export -> Export OptiFine Jem делаем экспорт модели в свою cem папку.
Теперь нужно выделить pack.mcmeta, pack.png, папку assets и запаковать в zip архив.
Кидаем это чудо в resourcepacks и активируем в игре. Для примера я использовал вместо иконки своё старое лого, так как под руку попалось именно оно. Но это мелочи, главное чтобы работало.
Результаты
В плоском мире создаём курицу и смотрим, получилось ли:
На этом вроде и всё. Вы только что создали свой ресурс пак для Minecraft на OptiFine, который меняет модель моба! Возможно и я ещё допилю свою подборку мобов, ведь процесс не сложный и достаточно занятный. А вам удачи и творческих успехов!
ПС. Не баг, а фича, или просто неудачный эксперимент:
Привет, если вы зашли сюда, значит действительно хотите узнать, как же делать модели в blockbench и добавлять их в свой майнкрафт!
Все используемые цвета, для чего используются
Оранжевый — Для описания расширения файла, либо же для расширения файлов!
Красный — Для строк внутри файлов
Зеленый — Для описания действий или же ресурсов с других сайтов
Синий — То, что нужно подметить для себя
Белый — Описание скринов
Желтый — Весь текст статьи
Фиолетовый — Адрес на вашем пк
Черный — Программы либо же сайты
Сейчас расскажу.
Для начала подготовимся, что нам нужно:
- Blockbench
- Minecraft ( Не обязательно лицензионный )
- Дефолтный ресурспак майнкрафта ( Как его вытащить расскажу по ходу гайда )
- Прямые руки
- Optifine
Первое что мы сделаем
Начнем с простого, нам нужно достать Ресурспак из игры
Для начала заходим в корневую папку игры .minecraft
По адресу: C:UsersИмя ПользователяAppDataRoaming.minecraft
Заходим в папку versions и открываем нужную вам версию с Optifine, далее мы открываем наш .jar файл с помощью WinRar ( или любой другой программы, что сможет рассмотреть файлы внутри .jar ), далее вам нужно перетащить файл assets из .jar файла в любую вам удобную папку или на рабочий стол
Вот мы и достали дефолтный Ресурспак из игры!
Приступим к сложному!
После установки
Blockbench, Нам нужно замоделить свою модель, сейчас распишу каким образом можно это сделать и какие модели можно вшивать в ваш майнкрафт
Первое это:
Цитата
какие модели мы можем вшивать в майнкрафт
Да совершенно любые начиная от квадратных ( Пиксельных до любых полигонально высоких или низких ),
Чтож, сейчас начнем делать нашу первую модель!
Для начала открываем Blockbench:
Нас встречает такой интерфейс, мы нажимаем на:
И попадаем в сетку редактирования вашей модели
Размеры мы указываем 64х64, так как майнкрафт не жует размеры меньше, именно так мы начнем создавать собственную модель. Модель вы можете создать любую на усмотрение!
Допустим я хочу создать кирку, указываю название в панели Имя Файла ( Ни на что не влияет! )
И начинаю делать модель, для этого гайда я не хочу париться насчет модели поэтому сделаю простой T образный предмет
Чтобы добавить куб мы используем меню справа, либо же кнопки CTRL+N
Далее мы начинаем делать нашу модель ( Ваша фантазия будет хорошо здесь помагать, ну и прямые руки конечно )
Вот мы сделали модель, теперь нам нужно её покрасить или наложить текстуру!
Но я буду добавлять текстуру ( Рисовать или красить можно научиться и самому, ведь я тут делаю обзор на то, как сделать свою модель! )
Для начала я возьму текстуру обычной печи из майнкрафта в виде PNG ( Эти текстуры можно достать из ресурспака, который мы вытащили сами! )
Вот я зашел в программу добыв текстуры и нажимаю на кнопку в панели слева «Добавить текстуру» либо же нажимаю CTRL+T
Как мы импортировали нашу текстуру, мы начинаем её растягивать по UV, но для начала её нужно перенести внутрь, как показано на скрине
Вот мы перенесли текстуру, и теперь поиграв с ползунками на UV Сетке, смотрим как меняется наша кирка ( Кстати на каждый куб своя текстура, я взял текстуру дерева для ручки и текстуру печи для нашей «Головы кирки», получилось примерно так:
Теперь разберемся как это вывести в наш майнкрафт, для начала экспортируем текстуру:
Но перед этим в разделе Предпросмотр справа сверху настройте вашу модельку ( Чтобы посмотреть как будет выглядеть ваша модель в игре, вы её устанавливаете на правильные места и даете им правильное положение в руках )
На скрине все видно, думаю там не сложно и вы разберетесь, вы же у меня умные
Приступим к экспорту. Так, нажимаем сверху кнопочку Файл > Экспортировать > Экспортировать модель Блока/Предмета
Нажали и сохранили!
Перед всем этим создайте папку в папке assets > minecraft ( внутри этой папки > optifine ( Обязательно с маленькой буквы ) >
cit > Тут на ваше усмотрение, но моя папка называется pickaxe
И переносим наш .json файл с Blockbench ( Кирку которую мы сделали ) в эту папку pickaxe и с ним текстуры, которые мы использовали
Далее создаем файл с названием pickaxe.properties
После «.» расширение файла
С такими настройками:
type=item
matchItems=minecraft:diamond_pickaxe
model=./kirka
nbt.display.Name=iregex:Kirka
Model = Ваш json file
Type = ваш тип предмета, тоесть у нас не block а item
nbt.display.Name = Название, можно сделать и на русском, для этого можно использовать сайт MINECRAFT TOOLS
matchItems= Тут мы используем обычный предмет, который будем заменять
Пример:
И мы копируем снизу эту строку:
u041au0438u0440u043au0430
И вставляем как nbt.display.Name=ipattern:u041au0438u0440u043au0430
Вместо pickaxe.json Используете ваше имя файла ( Кирка.json итд. )
Следующий этап, создаем свой ресурспак, тут все просто, assets переносим в вашу папку заранее созданную в папке resourcepack В директории майнкрафт, думаю тут вы тоже довольно просто разберетесь.
Чтобы вам не было сложно, я подготовил все нужные настройки для версии 1.18.2 файлов в виде TXT
Этот файл нам будет нужен, Для версии 1.18.2 нужно лишь изменить цифру Pack_format 9 внутри на Pack_format 8
И все скидываем в наш ресурспак, как пример у меня он называется YPACK
Как сделать свой ресурспак, думаю вы и сами найдете в интернете, на этом у меня все!
Как же залить в майнкрафт модель без переименования? Конечно же это легко сделать, просто заменив файл в майнкрафте на ваш файл .json, так вы быстро замените вашу текстуру, вот подробный видеогайд
Нужные Вам файлы:
В общем то цифра меняется в зависимости от версий, все это описано тут, по сути просто меняешь цыфорку и меняется настройка для версии :))
Pack mcmeta.txt
pickaxe properties.txt
kirka json.txt
Итог всего гайда, я добавил свою модель в майнкрафт:
Изменено 3 июля, 2022 пользователем Yunggxd
Редактирование темы
Blockbench это программа для создания и редактирования 3D моделей, в том числе мобов из Майнкрафт. С ее помощью вы можете легко изменить модель, текстуру, высоту и другие параметры любого моба. В этой статье вы найдете пошаговую инструкцию по изменению моба при помощи программы Blockbench.
Пошаговая инструкция
1. Переходим на официальный сайт blockbench.net и скачиваем программу для своей операционной системы;
2. Устанавливаем и запускаем программу. Нажимаем кнопку File на верхней панели и переходим во вкладку Plugins
3. Раскрываем вкладку Available и устанавливаем плагин CEM Template Loader нажав на кнопку Install
4. После чего закрываем появившееся сообщение и нажимаем на верхней панели Tools — Load CEM Template — Supported Entities
5. Выбираем моба которого хотим изменить и нажимаем Load
6. Откроется окно с 3D моделью моба. Вы можете выбрать любую часть тела моба на панели справа и изменить ее размер при помощи второго по счету инструмента на верхней панели.
7. Как только измените размер можете приступать к раскрашиванию модели, для этого откройте вкладку paint, выберите инструмент кисть и цвет. Раскрасьте модель по вашему желанию.
8. После того как вы закончите работать с моделью необходимо ее сохранить. Для этого нажмите File — Export — Export OptiFine JEM
9. Так же нужно сохранить скин модели. Для этого нажмите на значок дискеты в панели со скином которая находится слева.
10. Скачайте чистый ресурс пак для вашей версии майнкрафт
11. Создайте на рабочем столе папку optifine и внутри еще одну папку с названием cem
12. Переместите файл модели и ее скин в папку cem
13. Откройте чистый ресурс пак (не распаковывая его) перейдите в папку assets — minecraft и переместите в нее созданную папку optifine внутри которой находится папка cem с файлом модели и скином.
14. Нажмите сочетание клавиш Win + R, введите команду %appdata%
15. Перейдите в папку .minecraft — resourcepack. Переместите измененный ресурс пак в папку resourcepack.
16. Запустите игру, зайдите в настройки — и активируйте измененный ресурс пак (нужно что бы он оказался в правой колонке). Нажмите готово.
17. Создайте новый мир или нажмите F3 + T в старом для того что бы обновить ресурсы игры и наслаждайтесь измененными мобами.
Видео инструкция
Не всем игрокам в Minecraft нравится стандартный скин, с которым приходится играть в одиночном мире или на сервере. К счастью, есть уйма разных методов, позволяющих изменить образ персонажа. Далее я покажу доступные варианты настройки внешнего вида и расскажу, откуда можно скачать новые скины.
Методы установки скина в Майнкрафте
Каждый доступный вариант зависит от того, какую версию игры вы используете и желаете ли, чтобы другие игроки на сервере видели новый скин.
Вариант 1: Замена стандартного скина на ПК
Инструкция для тех, кто желает сменить стандартный скин только на компьютере, чтобы видеть его при загрузке одиночного мира.
- Откройте утилиту «Выполнить» (Win + R), введите %appdata% и нажмите по клавише Enter.
- После открытия нового каталога перейдите во внутреннюю папку Roaming.
- Откройте директорию с игрой, найдите подпапку Bin.
- Найдите в ней файл Char (скин) и замените его на тот, который скачали из сети заранее.
- Если же указанная директория отсутствует, перейдите в assest/skins и вставьте файл туда.
После этого можно сразу запускать клиент и открывать любой мир для проверки установки скина. Если игра уже была запущена, перезагрузите ее. В качестве альтернативы выступает следующая инструкция:
- Полученное изображение с файлом скина понадобится переименовать в steve.png.
- В той же утилите «Выполнить» вставьте команду %appdata%.minecraftversions и подтвердите ее ввод.
- Найдите каталог с версией игры, которую вы обычно запускаете.
- Перейдите по папкам assets > minecraft > textures > entity и вставьте с заменой новый скин.
Вариант 2: Использование сторонних лаунчеров
Для Майнкрафта существует множество лаунчеров, которые иногда устанавливаются автоматически, если речь идет не о лицензионной сборке игры. Обычно в главном меню такого лаунчера присутствует отдельная вкладка или меню, где можно выбрать скин, с которым будет запускаться игра.
Найдите на просторах интернета удобный лаунчер или скачайте тот, который предлагается сервером, а затем произведите настройку внешнего вида персонажа на свое усмотрение.
Вариант 3: Смена скина на сервере
При игре на каком-либо сервере, даже при отсутствии лаунчера, можно поменять скин на любой доступный с помощью команд, добавленных администрацией. Для этого придется зайти на официальный сайт сервера или вызвать команду подсказок, где и находится перечень всех доступных параметров.
Новый облик будут видеть все другие игроки на сервере. Учитывайте, что определенный набор скинов зачастую доступен только администрации или другим привилегированным игрокам, поэтому не удивляйтесь, если вдруг не найдете скин, как у другого пользователя на этом же сервере.
Вариант 4: Настройка скина в личном кабинете
Последний вариант подходит только обладателям лицензионной копии Minecraft. Такие пользователи могут открыть личный кабинет на официальном сайте, перейти в раздел «Скин» и выбрать один из доступных обликов. Соответственно, такой внешний вид видят все игроки на официальных серверах. Если вы запускаете игру через лаунчеры определенных серверов, в них действуют свои скины, о которых я говорил ранее.
Где взять лучшие скины для Minecraft
В завершение расскажу о том, где взять лучшие скины для Minecraft, если вы хотите загружать собственные файлы, а не пользоваться доступными в лаунчере или на официальном сайте. В таком случае придется использовать специальные сайты, распространяющие разные облики. Ниже вы видите пример того, как выглядит русскоязычный веб-ресурс, позволяющий скачать кастомные скины.
Я оставлю ссылки на два сайта, чтобы вы могли подобрать внешний вид своему персонажу для дальнейшей замены его при помощи Варианта 1:
- Nova Skin
- NameMC
Теперь вы знаете, как добавить новый скин в Minecraft разными способами.
Мощные игровые серверы для Minecraft от 3 руб./час
От 4 Гб ОЗУ, от 80 Гб на скоростном NVMe и стабильные 200 Мбит/сек
Узнать подробнее
Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей
Подписаться
Содержание
1 часть — Что такое ICustomModelLoader и как майнкрафт загружает модели.
2 часть — Подробное описание интерфейсов для создания моделей.
3 часть — Создание предмета с плоской моделью.
4 часть — Создание блока с простой и сложной моделями.
В новой версии единственный способ загружать модели для обычных блоков и предметов —
использовать ICustomModelLoader
. Об этом классе в этом уроке и пойдет речь.
ЧАСТЬ I
— Что такое ICustomModelLoader и как майнкрафт загружает модели.
Стандартный VanillaLoader
принимает все блоки и предметы, загружает модель из json-файла. Он ищет модели в самую последнюю очередь.
Интерфейс ICustomModelLoader
содержит в себе 2 метода: accepts
и loadModel
.
Первый метод определяет, будет ли данная моделька(параметр modelLocation
) загружена текущим лоадером. Второй метод уже подгружает модельку.
По логике вещей сначала ResourceLocation
модельки пробегается по accept’ам всех зарегистрированных загрузчиков моделей, если какой-то лоадер его цепляет — уже вызывается метод loadModel
. В конце концов модель зацепит VanillaLoader
(см выше).
loadModel
, как сказано выше, загружает: возвращает IModel
— необработанную модельку.
ЧАСТЬ II
— Подробное описание интерфейсов для создания моделей.
Класс IModel
содержит в себе много методов:
getDependencies — возвращает коллекцию зависимостей моделек(Collection<ResourceLocation>
). Т.е. данная моделька будет ‘выпечена'(об эFтом ниже) только после всех моделей-зависимостей.
getTextures — возвращает коллекцию текстур, используемых этой моделькой. Данный метод необязательно переопределять, но желательно — текстурки которые вы будете использовать в модельке все равно загрузятся, просто в другое время.
getDefaultState — возвращает IModelState
(трансформацию модельки) об этом ниже, в большинстве случаев можно оставить стандартную реализацию.
getClip — возвращает некий IClip
(Optional<? extends IClip>
). Этот вспомогательный интерфейс по большей части нужен для анимации и сглаживания(см net.minecraftforge.common.model.animation.Clips
— класс с множеством вариантов реализациий IClip
)
smoothLighting — возвращает модельку(IModel
) которая будет отображаться при включенном(параметр value
) ambient occlusion. В большинстве случаев рекомендуется оставить реализацию по умолчанию.
uvlock — возвращает модельку(IModel
), при вращении которой текстуры, применяемые к модели, не вращаются(при параметре value
== true
) вместе с ней. В большинстве случаев рекомендуется оставить реализацию по умолчанию.
gui3d — возвращает модельку(IModel
) которая будет отображаться в слоте инвентаря. (При значении параметра value
== false
модель должна быть плоской).
process — возвращает модельку(IModel
), с пользовательскими данными. Параметр ImmutableMap<String, String> customData
— пользовательские данные полученные из json-файла модельки, в виде ключ:значение. Вызывается только если моделька имеет json-файл blockstate.
Далее 2 самых важных метода, переопределение которых рекомендуется:
retexture — возвращает модельку(IModel
), которая будет загружена после ретекстурирования(не путать с перезагрузкой текстур F3+T
!). Метод должен возвращать
новую
модельку с
новыми
текстурами, старые должны быть автоматически удалены. Параметр ImmutableMap<String, String> textures
— старые текстурки в строковом формате.
bake — основной метод IModel
. По большому счету можно реализовать только его. ‘Выпекает’ (возвращает) IBakedModel
— готовую к рендеру модельку. Это происходит при запуске майнкрафта или при перезагрузке ресурсов(F3+T
). Параметр state
— это изначальная трансформация(IModelState
) полученная из getDefaultState
(см выше), format
— формат вершин(VertexFormat
), bakedTextureGetter
— функция(Function<ResourceLocation, TextureAtlasSprite>
), с помощью которой можно из ResourceLocation
получать TextureAtlasSprite
. Пример: bakedTextureGetter.apply(loc);
где loc
— путь до текстуры, bakedTextureGetter
— данная функция.
Разберем методы интерфейса IBakedModel
:
isAmbientOcclusion — возвращает boolean
, определяет можно ли к данной модельке применить AmbientOcclusion.
isGui3d — возвращает boolean
, определяет, будет ли данная модель рендерится плоской в слоте инвентаря или в виде выброшенного предмета (EntityItem
).
isBuiltInRenderer — возвращает boolean
, при true, текущая модель отрисовываться не будет, вместо неё будет рендерится TileEntityItemStackRenderer
. Этот метод используют такие ванильные блоки как сундук или флаг(баннер).
getOverrides — возвращает ItemOverrideList
, с помощью него можно удобно создавать отдельно модельку предмету, отдельно блоку(см ниже).
getParticleTexture — возвращает текстуру частиц(TextureAtlasSprite
), используется при создании частиц данной модельки. Например для предмета такие частицы появляются при съедании, для блока при ходьбе по нему.
handlePerspective — возвращает готовую модельку матрицу перспективы 4×4(Pair<? extends IBakedModel, Matrix4f>
, очень мощный метод для трансформации модельки, напрямую лучше не реализовывать. Параметр cameraTransformType — тип текущей трансформации(см net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType
)
getItemCameraTransforms — возвращает трансформацию модели предмета(ItemCameraTransforms
). Вызывается каждый кадр, когда рендерится предмет.
getQuads — основной метод данного интерфейса IBakedModel
, возвращает список ‘запеченных’ квадратов(List<BakedQuad>
), которые впоследствии передаются на графический процессор, где они уже будут отрисованы opengl’ем.
Примечание:
У блоков этот метод вызывается не каждый кадр, а только при обновлении рендера блока. Обновление рендера блока происходит либо когда блок впервые попал в поле зрения камеры, или когда рядом с ним обновился какой-либо blockstate. У предметов данный метод вызывается каждый кадр.
ЧАСТЬ III
— Создание предмета с плоской моделью.
Теперь немного практики. (УРА!)
Первым делом создадим свой ICustomModelLoader
public class TestCustomModelLoader implements ICustomModelLoader {
@Override
public boolean accepts(ResourceLocation modelLocation) {
return false;
}
@Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception {
return null;
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
}
Обязательно надо этот лоадер зарегистрировать.
Делать это нужно в специальном событии, на клиентской стороне разумеется.
@SubscribeEvent
public void eventRegisterModel(ModelRegistryEvent event){
ModelLoaderRegistry.registerLoader(new TestCustomModelLoader());
}
Все, теперь загрузчик моделей работает, осталось его только настроить.
Для примера создадим предмет. Я буду делать алмазный кинжал.
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
testItem = new Item();
testItem.setRegistryName("testitem");
ForgeRegistries.ITEMS.register(testItem);
}
Далее обычным способом(в инициализации мода на клиннтской стороне) зарегистрируем ModelResourceLocation
:
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(testItem,
0, new ModelResourceLocation(testItem.getRegistryName(),
"inventory"));
Все, предмет готов.
Теперь сделаем так, чтобы наш ICustomModelLoader
загрузил модель именно для этого предмета.
Переопределим метод accepts.
@Override
public boolean accepts(ResourceLocation modelLocation) {
/*
* напрямую modelLocation'ы лучше не сравнивать, т.к.
* в процессе загрузки моделей они несколько раз пересоздаются
*/
return modelLocation.toString().contains("testitem");
}
Теперь создадим класс модельки по всем законам моделькостроения.
public class TestItemModel implements IModel {
final ResourceLocation texture;
public TestItemModel(ResourceLocation texture){
this.texture = texture;
}
//Добавляем текстурки которые будем использовать
@Override
public Collection<ResourceLocation> getTextures() {
return Lists.newArrayList(texture);
}
//Строим саму модель
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
//получаем TextureAtlasSprite из ResourceLocation
TextureAtlasSprite textureAtlasSprite = bakedTextureGetter.apply(texture);
//Получаем список квадратов из текструки, для этого уже есть удобный метод.
ImmutableList<BakedQuad> quads = ItemLayerModel.getQuadsForSprite(0, textureAtlasSprite, format, state.apply(Optional.empty()));
return new TestItemBakedModel(quads, textureAtlasSprite);
}
}
И класс ‘испеченной’ модели
public class TestItemBakedModel implements IBakedModel {
List<BakedQuad> quads;
TextureAtlasSprite textureAtlasSprite;
public TestItemBakedModel(List<BakedQuad> quads, TextureAtlasSprite textureAtlasSprite){
this.quads = quads;
this.textureAtlasSprite = textureAtlasSprite;
}
//возвращаем квадраты для рендера
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
return quads;
}
//Пусть на нашу модельку действуем мягкое освещение
@Override
public boolean isAmbientOcclusion() {
return false;
}
//Делаем модельку плоской в GUI
@Override
public boolean isGui3d() {
return false;
}
//У нашего предмета нет TileEntityItemStackRenderer
@Override
public boolean isBuiltInRenderer() {
return false;
}
//Текстура частиц пусть будет такой же как и текстура предмета
@Override
public TextureAtlasSprite getParticleTexture() {
return textureAtlasSprite;
}
//Стандартный лист дефолтных трансформаций
@Override
public ItemOverrideList getOverrides() {
return ItemOverrideList.NONE;
}
}
Наконец-то напишем код для загрузки модели в нашем ICustomModelLoader
:
@Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception {
//эту проверку можно ибрать если одним лоадером прогружается лишь одна модель, или несколько одинаковых
if(modelLocation.toString().contains("testitem"))
return new TestItemModel(/* Указываем путь до текстурки предмета */ new ResourceLocation("items/diamond_sword"));
return null;
}
Все готово, теперь можно запускать.
Ура, получилось!
Подождите-ка…
Модель отображается неправильно…
Добавим в нашу испеченную модель такой код, трансформацию для кинжала:
//Трансформация предмета когда он выброшен в мире(EntityItem)
ItemTransformVec3f entity = new ItemTransformVec3f(/*Поворот по осям X Y Z*/new Vector3f(0f,0,0), new Vector3f(/*Смещение по осям X Y Z*/0.005f, 0.15f, 0.04f), new Vector3f(/*Масштаб по осям X Y Z*/0.55f, 0.55f, 0.55f));
//От третьего лица в правой руке
ItemTransformVec3f thirdPersonRight = new ItemTransformVec3f(new Vector3f(0f,-90,-160), new Vector3f(0.005f, -0.35f, 0.04f), new Vector3f(0.55f, 0.55f, 0.55f));
//От третьего лица в левой руке
ItemTransformVec3f thirdPersonLeft = new ItemTransformVec3f(new Vector3f(0f,-90,150), new Vector3f(0.005f, -0.40f, 0.1f), new Vector3f(0.55f, 0.55f, 0.55f));
//От первого лица в правой руке
ItemTransformVec3f firstPersonRight = new ItemTransformVec3f(new Vector3f(-140,-90,25), new Vector3f(0.03f, 0.23f, 0.104f), new Vector3f(0.68f, 0.68f, 0.68f));
//От первого лица в левой руке
ItemTransformVec3f firstPersonLeft = new ItemTransformVec3f(new Vector3f(-120,-90,25), new Vector3f(0.03f, 0.08f, 0.104f), new Vector3f(0.68f, 0.68f, 0.68f));
//Общая трансформация. Вместо некоторый отдельных ItemTransformVec3f, мы добавляем дефолтные, тк они не будут использованы обычным предметом
ItemCameraTransforms itemCameraTransforms = new ItemCameraTransforms(thirdPersonLeft, thirdPersonRight, firstPersonLeft, firstPersonRight, ItemTransformVec3f.DEFAULT, ItemTransformVec3f.DEFAULT, entity, ItemTransformVec3f.DEFAULT);
@Override
public ItemCameraTransforms getItemCameraTransforms() {
return itemCameraTransforms;
}
Теперь у нас модель отображается нормально.
ЧАСТЬ IV
— Создание блока с простой и сложной моделями.
Для этой части нужна специальная ‘обертка стандартных функций’, скачать ее можно в архиве, который прикреплен к этому уроку. Переместите данные из архива в исходники вашего мода(папка src/main/java).
(Все используемые ниже классы есть в библиотеке выше)
Разберем библиотеку по кусочку.
Первый класс — ModelBaker
Позволяет создавать коллекции ‘запеченных’ квадратов.
Имеет 1 статический экземпляр, с помощью которого можно вызывать основные методы, все из которых кроме bake
возвращают тот самый статический экземпляр.
Методы:
begin — начинает создание моделей
setTexture — устанавливает текстуру
putQuad — добавляет квадрат в локальный буфер
putCube — добавляет 6 квадратов(куб) в локальный буффер
putTexturedCube — добавляет куб в локальный буффер с uv равным положению текстурки, которую мы добавили в setTexture
bake — ‘запекает’ квадраты из локального буффера в коллекцию List<BakedQuad>
Чтобы создать модельку, надо:
1) начать ‘выпечку’ begin
2) установить текстуру setTexture
3) поместить произвольное кол-во квадратов(или кубов) в локальный буфер putQuad
4) ‘выпечь’ модельку bake
Второй класс — QuadBuilder
Позволяет создавать BakedQuad
с текстурой.
Имеет 1 статический экземпляр, с помощью которого можно вызывать основные методы, все из которых кроме build
возвращают тот самый статический экземпляр.
Методы:
begin — начинает создание квадрата
setTexture — устанавливает текстуру
putVertex — добавляет вершину в локальных буфер
tex — устанавливает uv для будущих вершин
build — собирает вершины из локального буфера в BakedQuad
Чтобы создать квадрат, надо:
1) начать сборку begin
2) установить текстуру setTexture
3) установить uv tex
4) поместить 4 вершины в локальный буфер putVertex
5) ‘построить’ модельку build
Остальные классы вспомогательные, ничего касающегося данного урока в них нет.
Теперь попробуем создать модель для блока!
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
testBlock = new Block(Material.IRON);
testBlock.setRegistryName("testname");
ForgeRegistries.BLOCKS.register(testBlock);
ForgeRegistries.ITEMS.register(new ItemBlock(testBlock).setRegistryName(testBlock.getRegistryName()));
}
Регистрируем ModelResourceLocation
итемблока:
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(testBlock),
0, new ModelResourceLocation(testBlock.getRegistryName(),
"inventory"));
Моделька:
public class BlockModel implements IModel{
final ResourceLocation loc;
public BlockModel(ResourceLocation loc){
this.loc = loc;
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
//текстурка
TextureAtlasSprite sprite = bakedTextureGetter.apply(loc);
//Получаем экземпляр для лучшей читабельности
ModelBaker baker = ModelBaker.INSTANCE;
//начинаем создание модели
baker.begin(state, format);
//привязываем текстурку
baker.setTexture(sprite);
//создаем куб размером 0.5 - это полная величина, т.е. куб будет размером с полноценный блок(1 метр)
baker.putTexturedCube(0,0,0,0.5f);
return new BlockBakedModel(/*Испекаем нашу модель*/baker.bake(), bakedTextureGetter.apply(loc), format, state);
}
@Override
public Collection<ResourceLocation> getTextures() {
return Lists.newArrayList(loc);
}
}
‘Печеная’ модель:
public class BlockBakedModel implements IBakedModel {
List<BakedQuad> bakedQuads;
TextureAtlasSprite textureParticle;
VertexFormat format;
IModelState state;
public BlockBakedModel(List<BakedQuad> bakedQuads, TextureAtlasSprite textureParticle, VertexFormat format, IModelState state){
this.bakedQuads = bakedQuads;
this.textureParticle = textureParticle;
this.format = format;
this.state = state;
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
return bakedQuads;
}
@Override
public boolean isAmbientOcclusion() {
return true;
}
@Override
public boolean isGui3d() {
return true;
}
@Override
public boolean isBuiltInRenderer() {
return false;
}
@Override
public TextureAtlasSprite getParticleTexture() {
return textureParticle;
}
@Override
public ItemOverrideList getOverrides() {
return ItemOverrideList.NONE;
}
}
Дополняем наш загрузчик моделей:
public class TestCustomModelLoader implements ICustomModelLoader {
@Override
public boolean accepts(ResourceLocation modelLocation) {
/*
* напрямую modelLocation'ы лучше не сравнивать, т.к.
* в процессе загрузки моделей они несколько раз пересоздаются
*/
return modelLocation.toString().contains("testitem") || modelLocation.toString().contains("testname");
}
@Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception {
if(modelLocation.toString().contains("testitem")) {
//весь предыдущий код в туториале можно заменить на стандартный класс
ImmutableList.Builder<ResourceLocation> list = ImmutableList.builder();
list.add(new ResourceLocation("items/diamond_sword"));
return new ItemLayerModel(list.build());
}
else if(modelLocation.toString().contains("testname")){
return new BlockModel(new ResourceLocation(/*Путь до текстуры блока*/"blocks/enchanting_table_top"));
}
return null;
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
}
Все готово, можно запускать.
Красота
Но с моделькой итемблока предмета все совсем плохо
Она громадная, загораживает четверть экрана.
К счастью эту проблему можно легко решить в пять строчек благодаря ItemOverrideList
(см выше)
Переопределим getOverrides
в IBakedModel
нашего блока:
@Override
public ItemOverrideList getOverrides() {
return ItemOverrideListBlock.INSTANCE;
}
В том же файле создаем непубличный класс ItemOverrideListBlock
:
class ItemOverrideListBlock extends ItemOverrideList{
public static ItemOverrideListBlock INSTANCE = new ItemOverrideListBlock(new ArrayList<>());
IBakedModel itemModel;
public ItemOverrideListBlock(List<ItemOverride> overridesIn) {
super(overridesIn);
}
@Override
public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) {
if(itemModel != null) return itemModel;
if(originalModel instanceof BlockBakedModel == false) return originalModel;
BlockBakedModel original = (BlockBakedModel) originalModel;
ModelBaker baker = ModelBaker.INSTANCE;
baker.begin(original.state, original.format);
TextureAtlasSprite sprite = original.textureParticle;
baker.setTexture(sprite);
//Делаем модельку в 2 раза меньше оригинальной
baker.putTexturedCube(0, 0, 0, 0.25f);
itemModel = new BlockBakedModel(baker.bake(), original.textureParticle, original.format, original.state);
return itemModel;
}
}
Примечание:
метод handleItemState
(как и getOverrides
) в классе ItemOverrideList
вызывается каждый кадр -> Он должен быть быстрым, для этого нужно кэшировать уменьшенную IBakedModel
(как в примере выше).
Все, можно запускать.
Выглядит ничем не хуже обычного, так даже интереснее смотрится!
Но все равно, это выглядит немного не так как обычный блок. Уберем выше сделанный ItemOverrideList у нашего блока, добавим трансформацию в ibakedmodel.
//Копируем все трансформации из block/generated.json
//Трансформация от первого лица в правой руке
ItemTransformVec3f firstperson_righthand = new ItemTransformVec3f(new Vector3f(0,45,0), new Vector3f(0, 0, 0), new Vector3f(0.40f, 0.40f, 0.40f));
//От первого лица в левой руке
ItemTransformVec3f firstperson_lefthand = new ItemTransformVec3f(new Vector3f(0,225,0), new Vector3f(0, 0, 0), new Vector3f(0.40f, 0.40f, 0.40f));
//От третьего лица
ItemTransformVec3f thirdperson_righthand = new ItemTransformVec3f(new Vector3f(75,45,0), new Vector3f(0, 0.15f, 0), new Vector3f(0.375f, 0.375f, 0.375f));
//На голове
ItemTransformVec3f fixed = new ItemTransformVec3f(new Vector3f(0,0,0), new Vector3f(0, 0, 0), new Vector3f(0.5f, 0.5f, 0.5f));
//В виде предмета в мире(EntityItem)
ItemTransformVec3f ground = new ItemTransformVec3f(new Vector3f(0,0,0), new Vector3f(0, 0.15f, 0), new Vector3f(0.25f, 0.25f, 0.25f));
//В графическом интерфейсе
ItemTransformVec3f gui = new ItemTransformVec3f(new Vector3f(30,225,0), new Vector3f(0, 0, 0), new Vector3f(0.625f, 0.625f, 0.625f));
//Общая транфсормация
ItemCameraTransforms itemCameraTransforms = new ItemCameraTransforms(thirdperson_righthand, thirdperson_righthand, firstperson_lefthand, firstperson_righthand, ItemTransformVec3f.DEFAULT, gui, ground, fixed);
@Override
public ItemCameraTransforms getItemCameraTransforms() {
return itemCameraTransforms;
}
Теперь блок в инвентаре выглядит нормально.
Давайте теперь создадим не просто куб, а много кубов в одной модельке. С моим апи это очень просто:
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
TextureAtlasSprite sprite = bakedTextureGetter.apply(loc);
TextureAtlasSprite spriteBooks = bakedTextureGetter.apply(new ResourceLocation("blocks/bookshelf"));
ModelBaker baker = ModelBaker.INSTANCE;
baker.begin(state, format);
baker.setTexture(sprite);
baker.putTexturedCube(0, 0.25f, 0, 0.25f);
baker.setTexture(spriteBooks);
baker.putCube(/*offsetX*/ 0f,/*offsetY*/ -0.25f,/*offsetZ*/ 0f,
/*scaleX*/0.5f, /*scaleY*/0.25f,/*scaleZ*/ 0.5f,
spriteBooks.getMinU(), spriteBooks.getMaxU(),spriteBooks.getMinV(),spriteBooks.getMaxV());
return new BlockBakedModel(/*Испекаем нашу модель*/baker.bake(), bakedTextureGetter.apply(loc), format, state);
}
Если хотите делать кубы с разными текстурами на разных гранях, в ModelBaker
есть удобный метод для создания квадратов.
Спасибо за внимание.
На чтение 7 мин. Просмотров 348 Опубликовано 05.02.2021
Этот учебник относится конкретно к официально поддерживаемой архитектуре модификации надстроек .
Содержание
- Резюме
- Требуемое время
- Необходимые инструменты
- Начало работы
- Формат модели Minecraft
- Кости и анимация
- Важное примечание!
- Изменение Creeper
- Результаты
- Добавляем еще
Резюме
Это руководство предназначено для опытных пользователей! Ожидается, что вы знакомы с форматом данных JSON. В противном случае ознакомьтесь с разделами JSON в руководстве по надстройке Behavior. В этом руководстве мы рассмотрим:
- Обзор формата модели Minecraft JSON
- Как изменять модели
Требуемое время
34 минуты
Необходимые инструменты
Вам понадобятся следующие программы, чтобы следовать этому руководству : Это будет сложно
- Текстовый редактор
Любой текстовый редактор должен работать, но мы бы предложили использовать какую-то программную IDE . Блокнот Windows отлично подходит для этого.
Начало работы
В этом уроке мы будем модифицировать крипер, чтобы у него было 3 головы! Прежде чем мы изменим крипер, давайте посмотрим на код, из которого состоят наши модели.
Формат модели Minecraft
Модели Minecraft определены с использованием JSON в файле с именем mobs.json
. Игроки могут найти его в пакете ресурсов Vanilla Minecraft по адресу Vanilla Resource Pack/models/mobs.json
. Этот файл содержит определение для каждой модели сущности. Каждое определение выглядит примерно так:
- Псевдокод шаблона объекта
"geometry.entityname": {"texturewidth": x, " textureheight ": y," кости ": [{" name ":" название части тела "," pivot ": [x, y, z]," cubes ": [{" origin ": [x, y, z] , "size": [x, y, z], "uv": [x, y]}]}]}
Примечание. Это просто примерный обзор того, как устроена модель каждой сущности. Если бы вы использовали это как есть, это не сработало бы!
format_version | Версия формата this использование модели | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
geometry.entityname | Имя объекта, которому эта модель принадлежит | ||||||||||||||||||||||
texturewidth | Ширина текстуры в пикселях для этого объекта | ||||||||||||||||||||||
textureheight | Высота текстуры в пикселях для этого объекта | ||||||||||||||||||||||
кости | Кости, составляющие скелет существа. Кости содержат геометрические данные, на которые влияет кость. Обратите внимание, что здесь может быть несколько костей, разделенных запятыми.
|
Кости и анимация
Кости — это то, что мы используем для анимации модели. Думайте об этом как о человеческом скелете! В человеческом теле кости движутся мышцами, и ваша плоть движется вместе с ними. В 3D-анимации кости перемещаются с помощью анимации, которая, в свою очередь, перемещает присоединенную к ним геометрию!
Важное примечание!
Модели не являются полностью данных пока нет. Хотя можно изменить что-то в модели, все же существуют определенные жестко запрограммированные значения, такие как: какие кости нужны сущности, с каким материалом рендерится сущность и какие анимации у нее есть. Это означает, что вы не можете просто скопировать и вставить геометрию сельчанина в раздел с пауками и надеяться, что это сработает! Пока эта система не станет более управляемой данными, вам нужно будет поэкспериментировать, чтобы достичь желаемых результатов!
Убедитесь, что вы правильно называете свои кости! Название костей для сущности должно быть таким же, как в пакете ресурсов Vanilla Minecraft.. Анимация и рендеринг модели полагаются на правильность этой информации, как описано выше!
Изменение Creeper
Теперь, когда мы рассмотрели, как формат модели Minecraft настроен, давайте немного доработаем лиану. Мы собираемся сделать так, чтобы у него было 3 головы: 2 снизу и 1 сверху, как пирамида.
- Сначала найдите раздел
geometry.creeper
в файлеmobs.json
Vanilla Minecraft и скопируйте его. .-
Vanilla Resource Pack/models/mobs.json
-
- Создать новую папку в вашем пакете ресурсов с именем
models
- Создайте новый файл JSON с именем
mobs.json
и сохраните его в папке с новыми моделями - Введите пару фигурных скобок (
{}
) в ваш новыйmobs.json
, а затем вставьтеgeometry.creeper
из файла модели Vanilla после левой фигурной скобки. - Теперь давайте сначала немного сдвинем его исходную голову влево. Для этого мы собираемся изменить компонент x исходной точки кости с именем «
head
» с -4 на -8. - Теперь скопируйте все в квадратных скобках для «
кубиков
» для «head
». Это должен быть просто текст, выделенный серым.- mobs.json — geometry.creeper — head section
{"name": "head", "pivot": [0.0, 18.0, 0.0], "cubes": [{"origin": [-8.0, 18.0, -4.0], "size": [8, 8, 8], "uv": [0, 0]}]},
- Добавьте запятую после правой фигурной скобки для только что скопированных строк.
- Вставьте скопированные строки после запятой.
- Добавьте запятую после правой фигурной скобки для строк, которые вы только что вставили.
- Вставьте скопированные строки снова после новая запятая
- Теперь у вас должно быть 3 пары фигурных скобок в «
кубиках
», у каждой из которых есть источник, размер и объект uv - В первых скопированных строках мы собираемся переместить эту головку вправо, изменив компонент x в исходной точке на 0 с -8
- Во второй копии измените компонент x в origin равно -4, а компонент y — 26
- Ваша головная секция для лианы теперь должна выглядеть (новый текст серым цветом):
- mob s.json — geometry.creeper — head section
{"name": "head", "pivot": [0.0, 18.0, 0.0 ], "кубики": [{"origin": [-8.0, 18.0, -4.0], "size": [8, 8, 8], "uv": [0, 0]}, {"origin": [0.0, 18.0, -4.0], "size": [8, 8, 8], "uv": [0, 0]}, {"origin": [-4.0, 26.0, -4.0], "size" : [8, 8, 8], "uv": [0, 0]}]},
Обратите внимание, что нам не нужно изменять UV для любой из новых голов, потому что мы скопировали UV-координаты старой головы, и мы не добавляем разные текстуры к новым головам.
Результаты
Добавляем еще
Если вы хотите изменить модель другого объекта, не забудьте добавить запятую после правой фигурной скобки geometry.creeper
.
- Псевдокод пример
Не забывайте запятую! (выделено красным)
{"geometry.creeper": {//материал модели} , "geometry.chicken": {//модель stuff}}
Поздравляем!
Если вы дошли до этого места, теперь вы должны знать все, что вам нужно знать, чтобы создавать свои собственные модели сущностей!
Если вы хотите создать настраиваемую сущность, которая использует настраиваемую модель вместо стандартной, то создание настраиваемой модели необходимо.
Редактор 3D-моделей можно использовать для простого создания пользовательской модели, но вы также можете использовать описанный выше метод для создания пользовательской модели. Файл пользовательской модели должен находиться в resource_pack/models/entity/
. Если вы ищете ванильный, модель обычно называется model_name.geo.json
, но только model_name.json
также работает