🇺🇦 Українська (Ukrainian - Ukraine)
🇺🇦 Українська (Ukrainian - Ukraine)
Зовнішній вигляд
🇺🇦 Українська (Ukrainian - Ukraine)
🇺🇦 Українська (Ukrainian - Ukraine)
Зовнішній вигляд
Ця сторінка написана для версії:
1.21.4
Іноді використання формату моделі Minecraft недостатньо. Якщо вам потрібно додати динамічне промальовування до візуальних елементів вашого блоку, вам потрібно буде використовувати BlockEntityRenderer.
Наприклад, нумо зробимо так, щоб блок лічильника зі статті про блокові-сутностей показував кількість натискань у зверху.
Для початку, нам треба створити BlockEntityRenderer для CounterBlockEntity.
Створюючи BlockEntityRenderer для CounterBlockEntity, важливо помістити клас у відповідний вихідний набір, наприклад src/client/, якщо ваш проєкт використовує розділені вихідні набори для клієнта та сервера. Доступ до пов’язаних із промальовуванням класів безпосередньо у вихідному наборі src/main/ небезпечний, оскільки ці класи можуть бути завантажені на сервер.
public class CounterBlockEntityRenderer implements BlockEntityRenderer<CounterBlockEntity> {
public CounterBlockEntityRenderer(BlockEntityRendererFactory.Context context) {
}
@Override
public void render(CounterBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
}
}Новий клас має конструктор із BlockEntityRendererFactory.Context як параметр. У Context є кілька корисних штук промальовування, наприклад ItemRenderer або TextRenderer. Крім того, включивши такий конструктор, стає можливим використовувати конструктор як сам функціональний інтерфейс BlockEntityRendererFactory:
public class FabricDocsBlockEntityRenderer implements ClientModInitializer {
@Override
public void onInitializeClient() {
BlockEntityRendererFactories.register(ModBlockEntities.COUNTER_BLOCK_ENTITY, CounterBlockEntityRenderer::new);
}
}Ви маєте зареєструвати промальовування блокових сутностей у своєму класі ClientModInitializer.
BlockEntityRendererFactory — це реєстр, який зіставляє кожен BlockEntityType зі спеціальним кодом відтворення на відповідний BlockEntityRenderer.
Тепер, коли у нас є промальовування, ми можемо малювати. Метод render викликається кожним кадром, і саме в ньому відбувається магія промальовування.
По-перше, нам потрібно змістити та повернути текст так, щоб він знаходився вище блоку.
INFO
Як випливає з назви, MatrixStack є стосом, що означає, що ви можете надсилати та витягувати перетворення. Гарне емпіричне правило полягає в тому, щоб додати новий блок на початку методу render і відкрити його в кінці, щоб промальовування одного блоку не впливав на інші.
Більше інформації про MatrixStack можна знайти в статті про базові концепції промальовування.
Щоб полегшити розуміння необхідних перекладів і поворотів, візуалізуємо їх. На цьому зображенні зелений блок – це місце, де буде намальовано текст, за замовчуванням у найдальшій нижній лівій точці блоку:

Отже, спочатку нам потрібно перемістити текст наполовину блоку по осях X і Z, а потім перемістити його вгору до верхньої частини блоку по осі Y:

Це робиться за допомогою одного виклику translate:
matrices.translate(0.5, 1, 0.5);Ось і переклад зроблено, обертання і масштаб залишаються.
За замовчуванням текст малюється на площині X-Y, тому нам потрібно повернути його на 90 градусів навколо осі X, щоб він був спрямований вгору на площині X-Z:
![Зелений блок у верхній центральній точці, спрямований догори] (/assets/develop/blocks/block_entity_renderer_3.png)
MatrixStack не має функції rotate, натомість нам потрібно використовувати multiply і RotationAxis.POSITIVE_X:
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));Тепер текст у правильному положенні, але він завеликий. BlockEntityRenderer промальовує весь блок на куб [-0.5, 0.5], тоді як TextRenderer використовує координати Y [0, 9]. Таким чином, нам потрібно зменшити його в 18 разів:
matrices.scale(1/18f, 1/18f, 1/18f);Тепер усе перетворення виглядає так:
matrices.push();
matrices.translate(0.5, 1, 0.5);
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
matrices.scale(1/18f, 1/18f, 1/18f);Як згадувалося раніше, Context, переданий у конструктор нашого промальовування, має TextRenderer, який ми можемо використовувати для малювання тексту. Для цього прикладу ми збережемо його в полі.
TextRenderer має методи для вимірювання тексту (getWidth), що корисно для центрування, і для його малювання (draw).
String text = entity.getClicks() + "";
float width = textRenderer.getWidth(text);
// draw the text. params:
// text, x, y, color, shadow, matrix, vertexConsumers, layerType, backgroundColor, light
textRenderer.draw(
text,
-width/2, -4f,
0xffffff,
false,
matrices.peek().getPositionMatrix(),
vertexConsumers,
TextRenderer.TextLayerType.SEE_THROUGH,
0,
light
);Метод draw приймає багато параметрів, але найважливіші з них:
Text (або String) для малювання;x і y;Matrix4f, що описує, як його слід трансформувати (щоб отримати один із MatrixStack, ми можемо використати .peek().getPositionMatrix(), щоб отримати Matrix4f для самого верхнього запису).І після всієї цієї роботи ось результат:
