1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

マインクラフトmodding キー、画面、Guiの搭載

Last updated at Posted at 2023-05-05

この記事はマインクラフトforge 1.19 ~ 1.19.4について書いてあります。

参考程度にどうぞ。

記事を書いた理由

1.19は新しくて参考になる記事がなかったため

前提

MODIDはexamplemodとし、languageファイルは以下の通り

en_us.json
{
  "key.examplemod.category": "Key category",
  "key.examplemod.setting": "Key setting",
  "screen.examplemod.setting": "Example screen",
  "screen.examplemod.sub": "Sub screen",
  "button.examplemod.setting": "Button!"
}

resources/assets/examplemod/lang/下に置く(MODIDは小文字)

継承元クラス、イベントクラス以外のクラス名に決まりはありません。ただ、分かりやすくすることをお勧めします。

キー設定

キー設定

KeyManager.java
package examplemod;

import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = "examplemod")
public class KeyManager {
  static KeyMapping setting = new KeyMapping(
      "key.examplemod.setting",
      KeyConflictContext.IN_GAME,
      InputConstants.Type.KEYSYM,
      'J', // char型
      "key.examplemod.category"
  );

  @SubscribeEvent
  public static void keyRegister(RegisterKeyMappingsEvent event) { // 引数の型は変更しない。
    event.register(setting);  // キー設定を登録
  }

  @SubscribeEvent
  public static void keyPressed(InputEvent.Key event) {
    if (setting.consumeClick()) {  // もし J キーが押されたら
      Minecraft.getInstance().setScreen(new SettingScreen());  // SettingScreenを開く
    }
  }
}

スクリーン

init() 内に初期内容を書く。今回は、SettingScreenからボタンを押してSubScreenに移動するスクリプトを書く

スクリーン

SettingScreen.java
package examplemod;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;

public class SettingScreen extends Screen {
  public SettingScreen() {
    super(Component.translatable("screen.examplemod.setting"));
  }

  @Override
  protected void init() {
    Button button = Button.builder(
            Component.translatable("button.examplemod.setting"), // Button! と表示
            b -> Minecraft.getInstance().setScreen(new SubScreen(this))  // ボタンを押したらSubScreenに移動
        )
        // スクリーンの幅の半分から左に75、高さの半分から10上から描画する
        .pos(this.width / 2 - 75, this.height / 2 - 10)
        .size(150, 20)  // 横150、高さ20のボタンを描画
        .build();  // インスタンス化
    addRenderableWidget(button);
  }
}
SubScreen.java
package examplemod;

import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;

public class SubScreen extends Screen {
  Screen parent;
  public SubScreen(Screen parent) {
    super(Component.translatable("screen.examplemod.sub"));
    this.parent = parent;
  }
  @Override
  protected void init() {
    // ここに描画内容を書く
  }
}

GUI

左上にプレイヤーの現在座標を表示

座標


MainGui.java
package examplemod;

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.event.RenderGuiOverlayEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.awt.*;

@Mod.EventBusSubscriber(modid = "examplemod")
public class MainGui extends Gui {
  static Minecraft mc = Minecraft.getInstance();
  public MainGui() {
    super(Minecraft.getInstance(), Minecraft.getInstance().getItemRenderer());
  }

  @SubscribeEvent
  public static void onPostRenderGuiOverlayEvent(RenderGuiOverlayEvent.Post event) { // 画面が表示されたとき
    if (mc.player == null) return;
    RenderSystem.setShaderColor(
        1f,
        1f,
        1f,
        1f
    );
    PoseStack stack = event.getPoseStack();
    Vec3 vec3 = mc.player.position();
    String pos = String.format("X: %.4f / Y: %.4f / Z: %.4f", vec3.x, vec3.y, vec3.z);  // 下4桁まで
    stack.pushPose();
    mc.font.draw(
        stack,
        pos,  // 表示する文字列
        0,  // 座標 0, 0 に描画
        0,
        Color.GREEN.getRGB()  // 緑色
    );
    stack.popPose();
  }
}

最後に

@net.minecraftforge.eventbus.api.SubscribeEventはイベント検知をするときに使う。
このアノテーションのみを使用する場合、Modアノテーションの付けられたクラスのコンストラクタ内で、

ExampleMod.java
MinecraftForge.EVENT_BUS.register(new Hoge());

register内にSubscribeEventアノテーションの付けられたクラスのインスタンスを登録する必要がある。

これが面倒くさい場合は、
@net.minecraftforge.fml.common.Mod.EventBusSubscriberアノテーションを使うこともできる。
クラスにこれを付けると、register()に登録する必要がなくなる。
ただ、@SubscribeEventを付けられたメソッドはstaticを付ける必要がある。

mdkをダウンロードしたサンプルコードの内部に

// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent

とある。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?