この記事は、Minecraft Command Advent Calendar 2025 16日目の記事です。![]()
はじめに
私は約5年前に思い立って以来、マイクラRPG(未だ完成していない!!)のUIを試行錯誤しながら延々と手を加えてきた者なのですが、時を経て知見がまとまってきたので、この機会に解説してみます。RPGに限らず何事もUIがリッチだと完成度が高く見えるもので、幅広い場面で活用できる知見をざっと紹介していきます。
また1.21.5より、テキストの記述方法が「JSONテキスト」から「SNBT」というフォーマットに変わったため、アップデート作業がてら自身の日記としてここに記しておきます。
Minecraft Java版 ver 1.21.11 時点の情報となります。
actionbar UIとは?
それぞれの要素が独自に動きまくる、バニラライクなRPG風UI
早い話、こういったものです。画面下部の「actionbar」に/titleコマンドでテキストやカスタムフォントを表示し、これをピクセル単位で位置調整することで、動画のような賑やかなUIを作ることができます。
とこのように、マイクラに既存のHPや空腹度表示・経験値バーといったUIの上に、更に画面上に情報を増やしたい時に大いに活用ができます。
プレイヤースコアの表示 ───────
基本的には以下のような/titleコマンドを用いてUIを作っていきます。
まずはプレイヤーのスコアを表示させるところから。
title @s actionbar ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
\uE100(♡アイコン)、2px分の空白、HP、"/"、最大HPの順番で表示される
ここで大切な概念としては先頭の""(空白テキスト)。テキストのリストにおいて「先頭の要素に設定された書式は、各要素で上書きされない限り継承される」ため、先頭でフラットな書式を設定することで、2要素目のshadow_colorなどが以降に影響しないようにしています。
参照: https://ja.minecraft.wiki/w/テキストコンポーネント#データ型
カスタムフォントの設定
{
"providers": [
{
"type": "space",
"advances": {
"\uE820": 0,
"\uE821": 1,
"\uE822": 2,
# ---------- 中略 ---------- #
"\uF82F": 32768
}
},
{
"type": "bitmap",
"file": "resource:font/heart.png",
"ascent": 0,
"height": 9,
"chars": [
"\uE100"
]
}
}
}
♡アイコンはカスタムフォント1で定義しており、ascent, heightを上手く設定することで上下の位置や大きさを設定できます。ascentもとい上下の位置調整については後で詳しく!
title @s actionbar {"type":"object","atlas":"gui","sprite":"hud/heart/full"}
また、1.21.9で追加されたobjectを用いてテクスチャアトラスの参照ができる件については、ハートの大きさや上下の位置調整が困難だったことから断念しました。残念。
ストレージを用いたテキスト表示
続いて今後の為にテキストをストレージに格納し、/titleコマンドをスリムにしていきます。
# ストレージの準備
+ data modify storage player:temp hp set value ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
# UIの表示
- title @s actionbar ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
+ title @s actionbar ["",{"nbt":"hp","storage":"player:temp","interpret":true}]
# リセット
+ data remove storage player:temp hp
一見意味のない作業のように見えますが、UIパーツに名前を付けて管理できる点や、繰り返し同じパーツを使いたい時(後述: テキストの左揃え・右揃え)等で使い勝手が良くなります。
テキストの左揃え・右揃え
続いてテキストを左右に揃えていきます。actionbarに表示されるテキストは中央揃えなので、例えばスコアMaxHPの値が増えた場合、現状だと以下のような挙動になります。
これではスコア以外で画面に固定したいUIがある場合は大変都合が悪く、値に応じて全てのUIの位置をずらす等といった処理を行う必要が出てきてしまいます。そこで、左右揃え。
# ストレージの準備
data modify storage player:temp hp set value ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
# UIの表示
- title @s actionbar ["",{"nbt":"hp","storage":"player:temp","interpret":true}
+ title @s actionbar ["","\uF82F",{"nbt":"hp","storage":"player:temp","interpret":true},"\uF82F",{"nbt":"hp","storage":"player:temp","interpret":true}]
# リセット
data remove storage player:temp hp
ひと手間加えるだけで、あら不思議。右揃えのHPスコアが完成します。
...そのひと手間とは、具体的に「画面外右側にもHPスコアを表示する」です。
「画面内のテキスト幅が右に伸びる分」と「画面外右側のテキスト幅が左に伸びる分」が相殺することで、画面内のスコアは左だけに伸びているように見えます。
画面外に追いやっているテキスト(黄色で表示)を画面内に戻してみるとこんな感じ。
同様の手法で、レベルや所持ゴールド表示(左揃え)も実装。
# ストレージの準備
data modify storage player:temp hp set value ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
+ data modify storage player:temp lvl set value [{"text":"","color":"#E0E0E0"},"Lv.\uF822",{"score":{"name":"@s","objective":"LVL"},"color":"white","bold":true},"\uF822(",{"score":{"name":"@s","objective":"EXP"},"color":"#9EE082"},"/",{"score":{"name":"@s","objective":"NextEXP"}},") "]
+ data modify storage player:temp gold set value ["",{"score":{"name":"@s","objective":"Gold"}},{"text":"G","color":"#FFEE59"},"\uF822",{"text":"\uE101","shadow_color":0}]
# UIの表示(2~3行目:左画面外、5~7行目画面内、9行目右画面外)
title @s actionbar ["",\
+ {"nbt":"lvl","storage":"player:temp","interpret":true},\
+ {"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true},\
+ {"nbt":"lvl","storage":"player:temp","interpret":true},\
+ {"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# リセット
data remove storage player:temp hp
+ data remove storage player:temp lvl
+ data remove storage player:temp gold
ちなみに当然HPの左側や所持ゴールドの右側(アイコンが配置されている表示部分)は動いてしまうので、固定したいUIは今後ストレージhpとlvlの間に追加していきます。
スコアに応じたアイコンの表示 ────
ここまで来れば、以降の発想は結構シンプルです。スコアに応じてストレージにカスタムフォントを格納し、それを/titleコマンドに追加していくだけ!まぁそれが大変なのですが!
# ---------- 前略 ---------- #
+ # HPバー
+ # HPの割合計算
+ scoreboard players operation $MaxHP Temporary = @s MaxHP
+ scoreboard players operation $MaxHP Temporary /= #5 Constant
+ execute store result storage macro:temp hp_bar.value int 1 run scoreboard players add $MaxHP Temporary 10
+ # 適用
+ function player:actionbar/hp_bar with storage macro:temp hp_bar
# UIの表示
title @s actionbar ["",\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true},\
+ {"nbt":"hp_bar","storage":"player:temp","interpret":true},\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# ---------- 後略 ---------- #
# マクロも活用してhp_barに適切なフォントを格納
execute if score $MaxHP Temporary matches ..9 run data modify storage player:temp hp_bar set value {"text":"\uE211","shadow_color":0}
$data modify storage player:temp hp_bar set value {"text":"\uE2$(value)","shadow_color":0}
execute if score $MaxHP Temporary matches 50.. run data modify storage player:temp hp_bar set value {"text":"\uE250","shadow_color":0}
最終的にはHPバーの位置を揃えて、60/100をアイコンで表現するイメージ
カスタムフォントの設定
{
"providers": [
# ---------- 中略 ---------- #
{
"type": "bitmap",
"file": "resource:font/hp_bars.png",
"ascent": 0,
"height": 20,
"chars": [
"\uE211\uE212\uE213\uE214\uE215",
"\uE216\uE217\uE218\uE219\uE220",
"\uE221\uE222\uE223\uE224\uE225",
"\uE226\uE227\uE228\uE229\uE230",
"\uE231\uE232\uE233\uE234\uE235",
"\uE236\uE237\uE238\uE239\uE240",
"\uE241\uE242\uE243\uE244\uE245",
"\uE246\uE247\uE248\uE249\uE250"
]
}
}
}
結構なゴリ押しであることは実装からも読み取れると思いますが、マクロを活用することでいくらかスマートに実装できていると思います。また、テクスチャ側で全アイコンが同じ幅を持つよう、空白箇所にも透明度1%やらの何らかのピクセルを描いておく必要があります。
あえて描かずに、空白のまま残して自動的に左詰めさせる仕様2を使うときもありますが。
同様の手法で、職業スキル用のアイコンも実装。
# ---------- 前略 ---------- #
+ # 職業スキルアイコン
+ execute store result storage macro:temp skill_icon.max_arrow int 1 run scoreboard players get @s MaxHArrow
+ execute store result storage macro:temp skill_icon.arrow int 1 run scoreboard players get @s HArrow
+ function player:actionbar/hunter/arrow with storage macro:temp skill_icon
# UIの表示
title @s actionbar ["",\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true},\
{"nbt":"hp_bar","storage":"player:temp","interpret":true},\
+ {"nbt":"skill_icon","storage":"player:temp","interpret":true},\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# ---------- 後略 ---------- #
$data modify storage player:temp skill_icon set value {"text":"\uE5$(max_arrow)$(arrow)","shadow_color":[0,0,0,0.5]}
{
"providers": [
# ---------- 中略 ---------- #
{
"type": "bitmap",
"file": "resource:font/arrow_icons.png",
"ascent": 0,
"height": 9,
"chars": [
"\uE510\uE511\uE520",
"\uE521\uE522\uE530",
"\uE531\uE532\uE533"
]
}
}
}
アニメーションアイコン
続いてアニメーションを持つUIの表示。とはいえ名前ほど大層なことはしていなくて、やっていることとしてはタイマースコアに応じたアイコンの表示。手順も先程とほぼ同じです。
# ---------- 前略 ---------- #
+ # スキルバー
+ # スキルクールダウンの割合計算
+ scoreboard players operation $SkillTimer Temporary = @s SkillTimer
+ scoreboard players operation $SkillTimer Temporary /= #20 Constant
+ scoreboard players add $SkillTimer Temporary 10
+ execute if entity @s run scoreboard players add $SkillTimer Temporary 40
+ execute store result storage macro:temp skill_bar.value int 1 run scoreboard players get $SkillTimer Temporary
+ # 適用
+ function player:actionbar/skill_bar with storage macro:temp skill_bar
# UIの表示
title @s actionbar ["",\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true},\
{"nbt":"hp_bar","storage":"player:temp","interpret":true},\
{"nbt":"skill_icon","storage":"player:temp","interpret":true},\
+ {"nbt":"skill_bar","storage":"player:temp","interpret":true},\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# ---------- 後略 ---------- #
# マクロを用いてskill_barに適切なフォントを格納
$data modify storage player:temp skill_bar set value {"text":"\uE3$(value)","shadow_color":0}
カスタムフォントの設定
{
"providers": [
# ---------- 中略 ---------- #
{
"type": "bitmap",
"file": "resource:font/skill_bars.png",
"ascent": 0,
"height": 5,
"chars": [
"\uE310\uE311\uE312\uE313",
"\uE314\uE315\uE316\uE317",
"\uE318\uE319\uE320\uE321",
"\uE322\uE323\uE324\uE325",
"\uE326\uE327\uE328\uE329",
"\uE330\uE331\uE332\uE333",
"\uE334\uE335\uE336\uE337",
"\uE338\uE339\uE340\uE341",
"\uE350\uE351\uE352\uE353",
"\uE354\uE355\uE356\uE357",
"\uE358\uE359\uE360\uE361",
"\uE362\uE363\uE364\uE365",
"\uE366\uE367\uE368\uE369",
"\uE370\uE371\uE372\uE373",
"\uE374\uE375\uE376\uE377",
"\uE378\uE379\uE380\uE381"
]
}
}
}
先程のHPバーでも同じような定義をしていましたが、フォントの割り当てを\uE310から始めることで、下2桁をマクロで設定することを可能にして不用意なエラー3を避けています。
同様の手法で、酸素ゲージ表示も実装。
# ---------- 前略 ---------- #
+ # 酸素ゲージ
+ data modify storage player:temp oxygen set value {"text":"\uE60A"}
+ # 酸素ゲージの割合を計算
+ scoreboard players operation $OxygenRatio Temporary = @s Oxygen
+ scoreboard players operation $OxygenRatio Temporary *= #100 Constant
+ scoreboard players operation $OxygenRatio Temporary /= @s MaxOxygen
+ # 気泡が破裂するアイコン
+ execute if entity @s[tag=Underwater] if score $OxygenRatio Temporary matches 1 run data modify storage player:temp oxygen set value {"text":"\uE60B","shadow_color":0}
+ execute if entity @s[tag=Underwater] if score $OxygenRatio Temporary matches 21 run data modify storage player:temp oxygen set value {"text":"\uE60C","shadow_color":0}
+ execute if entity @s[tag=Underwater] if score $OxygenRatio Temporary matches 41 run data modify storage player:temp oxygen set value {"text":"\uE60D","shadow_color":0}
+ execute if entity @s[tag=Underwater] if score $OxygenRatio Temporary matches 61 run data modify storage player:temp oxygen set value {"text":"\uE60E","shadow_color":0}
+ execute if entity @s[tag=Underwater] if score $OxygenRatio Temporary matches 81 run data modify storage player:temp oxygen set value {"text":"\uE60F","shadow_color":0}
+ # 割合に応じて気泡アイコンを表示
+ scoreboard players add $OxygenRatio Temporary 19
+ scoreboard players operation $OxygenRatio Temporary /= #20 Constant
+ execute store result storage macro:temp oxygen.value int 1 run scoreboard players get $OxygenRatio Temporary
+ # 酸素ゲージが満タンの時は非表示
+ execute unless score @s Oxygen = @s MaxOxygen run function player:actionbar/oxygen with storage macro:temp oxygen
# UIの表示
title @s actionbar ["",\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true},\
{"nbt":"hp_bar","storage":"player:temp","interpret":true},\
{"nbt":"skill_icon","storage":"player:temp","interpret":true},\
{"nbt":"skill_bar","storage":"player:temp","interpret":true},\
+ {"nbt":"oxygen","storage":"player:temp","interpret":true},\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# ---------- 後略 ---------- #
$execute unless data storage player:temp oxygen.shadow_color run data modify storage player:temp oxygen set value {"text":"\uE60$(value)","shadow_color":0}
{
"providers": [
# ---------- 中略 ---------- #
{
"type": "bitmap",
"file": "resource:font/oxygen.png",
"ascent": 0,
"height": 9,
"chars": [
"\uE600\uE60A",
"\uE601\uE60B",
"\uE602\uE60C",
"\uE603\uE60D",
"\uE604\uE60E",
"\uE605\uE60F"
]
}
}
}
またここで、minecraft/textures/gui/sprites/hudの中の酸素ゲージや防具アイコン、経験値バー等を編集して非表示にしたり、自分好みに表示させています。
ステータスバフアイコン
画面中央に広くスペースを確保し、受けているバフに応じてアイコンを表示させています。アイコンはそれぞれ効果時間を表し、それがバフかデバフか一目でわかるように工夫されています。様々な状況に応じてアイコンを操る、集大成のようなUI。
左右のpxを上手に調整して、これは中央揃えに。よくやったものだ。
...基本的なアイデアはそんな感じですが、解説するのはちょっと骨が折れそうだ!
ということでまたいつか、番外編の動画やらで解説することにします。
経験値バー操作 ───────────
ホットバーの上に位置する経験値表示用の既存のUI。これを自在に操作することで、独自のUIを作っていきます。今回はMPを表示するものとして。...出来上がったものがこちら!!
実装の詳細
# MPバー操作
# MPの割合計算
scoreboard players operation @s MPRatio = @s MP
scoreboard players operation @s MPRatio *= #835 Constant
scoreboard players operation @s MPRatio /= @s MaxMP
# MPバーを適用
execute unless score @s PrevMPRatio = @s MPRatio run function player:status/mp/bar/_
# 操作前のレベルを一旦保存
execute store result score $XPBarLevels Temporary run scoreboard players get @s MP
# レベル129はポイントが 0~1002 なので割合を調べるのに最適
xp set @s 129 levels
execute store result score $XPBarPoints Temporary run xp query @s points
# MPの割合(0~100%)との違いを調べる
scoreboard players operation $XPBarDif Temporary = @s MPRatio
scoreboard players operation $XPBarDif Temporary -= $XPBarPoints Temporary
scoreboard players operation $XPBarDif Temporary /= #8 Constant
# 経験値ポイント加算
xp set @s 0 points
scoreboard players operation $XPBarPoints Temporary += $XPBarDif Temporary
execute store result storage macro:temp xp_bar.point int 1 run scoreboard players get $XPBarPoints Temporary
function player:status/mp/bar/set_point with storage macro:temp xp_bar
# レベル数値加算
xp set @s 0 levels
execute store result storage macro:temp xp_bar.level int 1 run scoreboard players get $XPBarLevels Temporary
function player:status/mp/bar/set_level with storage macro:temp xp_bar
# MPに変化がある時だけfunctionを常時実行
scoreboard players set @s PrevMPRatio -1
execute if score $XPBarDif Temporary matches 0 run scoreboard players operation @s PrevMPRatio = @s MPRatio
# リセット
data remove storage macro:temp xp_bar
scoreboard players reset $XPBarDif Temporary
scoreboard players reset $XPBarLevels Temporary
scoreboard players reset $XPBarPoints Temporary
$xp set @s $(point) points
$xp set @s $(level) levels
経験値操作については過去に動画4で一度解説したことがあるので、未見の方はそちらを見ていただくとより掴めるかと思います。マクロの登場によって動画投稿時点より最終的なpoint, levelの設定が簡単になったので、実装を見比べてみるのもまた一興。
テキスト・アイコンの上下位置調整 ──
さて、仕上げとして、ようやくこれらをいい感じに並べて、いい感じにしていきましょう。まずはアイコンから。フォントの定義において、ascentの値をいじることで上下可能です。
この時、ascentの値がheightを上回ると読み込みエラーが起きてしまうため注意。
![]()
参照(ソース): https://ja.minecraft.wiki/w/フォントのカスタマイズ より
続いてテキストの位置調整。以前、動画では自作のフォントを作る必要がある!と自信満々に言ってしまっていましたが、もう少し簡単な手法を見つけたのでそちらを紹介します。
「テキストをアイコンで上書きしたフォントを定義する」手法。default.jsonの入っているフォルダにて新しく適当なjsonファイルを作成し、中身をこのように定義します。重要な部分は2要素目のui_text.pngを割り当てしている部分。
{
"providers": [
{
"type": "space",
"advances": {
" ": 4,
"\uF822": 2
}
},
{
"type": "bitmap",
"file": "resource:font/ui_text.png",
"ascent": -22,
"height": 7,
"chars": [
"0123456789Lv.(/)G"
]
},
{
"type": "bitmap",
"file": "resource:font/heart.png",
"ascent": -21,
"height": 9,
"chars": [
"\uE100"
]
}
]
}
0123456789Lv.(/)Gのテキストにそれぞれ画像を割り当てしていく
こうすることで「\uE100→♡」となるように「1→1の画像」となるわけです。画像(bitmap)はascentタグを用いることで簡単に上下させることが可能なので、アイコンと同様の操作を行ってテキストも上下していきます。
# ストレージの準備
- data modify storage player:temp hp set value ["",{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
- data modify storage player:temp lvl set value [{"text":"","color":"#E0E0E0"},"Lv.\uF822",{"score":{"name":"@s","objective":"LVL"},"color":"white","bold":true},"\uF822(",{"score":{"name":"@s","objective":"EXP"},"color":"#9EE082"},"/",{"score":{"name":"@s","objective":"NextEXP"}},") "]
- data modify storage player:temp gold set value ["",{"score":{"name":"@s","objective":"Gold"}},{"text":"G","color":"#FFEE59"},"\uF822",{"text":"\uE101","shadow_color":0}]
+ data modify storage player:temp hp set value [{"text":"","font":"y-22px"},{"text":"\uE100","shadow_color":0},"\uF822",{"score":{"name":"@s","objective":"HP"}},"/",{"score":{"name":"@s","objective":"MaxHP"}}]
+ data modify storage player:temp lvl set value [{"text":"","color":"#E0E0E0","font":"y-16px"},"Lv.\uF822",{"score":{"name":"@s","objective":"LVL"},"color":"white","bold":true},"\uF822(",{"score":{"name":"@s","objective":"EXP"},"color":"#9EE082"},"/",{"score":{"name":"@s","objective":"NextEXP"}},") "]
+ data modify storage player:temp gold set value [{"text":"","font":"y-16px"},{"score":{"name":"@s","objective":"Gold"}},{"text":"G","color":"#FFEE59"},"\uF822",{"text":"\uE101","shadow_color":0}]
# ---------- 後略 ---------- #
テキスト・アイコンの左右位置調整 ──
ラスボス、左右位置調整です。なぜこれを最後にやるかというと、一つを目的の位置に動かそうとするたび、全てが連動して動いてしまうためです。一気にやったほうがお得。また、左右の位置調整にはspaceを使っていきます。...と出来上がっていく様子がこちら!!
# ---------- 前略 ---------- #
# UIの表示
title @s actionbar ["",\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
+ "\uF82F",{"translate":"space.-79"},\
+ {"nbt":"hp","storage":"player:temp","interpret":true},{"translate":"space.6"},\
{"nbt":"hp_bar","storage":"player:temp","interpret":true},\
+ {"nbt":"skill_icon","storage":"player:temp","interpret":true},{"translate":"space.53"},\
+ {"nbt":"skill_bar","storage":"player:temp","interpret":true},{"translate":"space.2"},\
+ {"nbt":"oxygen","storage":"player:temp","interpret":true},{"translate":"space.-126"},\
{"nbt":"lvl","storage":"player:temp","interpret":true},\
{"nbt":"gold","storage":"player:temp","interpret":true},\
+ {"translate":"space.8"},"\uF82F",\
{"nbt":"hp","storage":"player:temp","interpret":true}]
# ---------- 後略 ---------- #
カスタムフォントの設定
{
"providers": [
{
"type": "space",
"advances": {
"\uF800": 0,
"\uF801": -1,
"\uF802": -2,
"\uF803": -3,
"\uF804": -4,
"\uF805": -5,
"\uF806": -6,
"\uF807": -7,
"\uF808": -8,
"\uF809": -16,
"\uF80A": -32,
"\uF80B": -64,
"\uF80C": -128,
"\uF80D": -256,
"\uF80E": -512,
"\uF80F": -32768,
"\uF820": 0,
"\uF821": 1,
"\uF822": 2,
"\uF823": 3,
"\uF824": 4,
"\uF825": 5,
"\uF826": 6,
"\uF827": 7,
"\uF828": 8,
"\uF829": 16,
"\uF82A": 32,
"\uF82B": 64,
"\uF82C": 128,
"\uF82D": 256,
"\uF82E": 512,
"\uF82F": 32768
}
},
# ---------- 後略 ---------- #
]
}
{
"space.-126": "\uF80B\uF80A\uF809\uF808\uF806",
"space.-79": "\uF80B\uF808\uF807",
"space.2": "\uF822",
"space.6": "\uF826",
"space.8": "\uF828",
"space.53": "\uF82A\uF829\uF825"
}
以前はAmberWatさんの制作したNegativeSpaceFontを導入する必要がありましたが、今やdefault.json内でspaceを定義するだけでOK。とてもシンプルになりました。
さいごに
実際にストレージに適切なアイコンを格納する部分や、諸々actionbar以外の細かな処理でかなり解説を端折った部分があったと思います!!申し訳ないです...!全てgithubで公開しているので、奥で動いている処理に興味のある方はそこまで覗いてもらえると嬉しいです。
長いことUI周りの知見を外に出していなかった自覚があるので、この機会に放出できてよかったです。カスタムフォントの定義であったり、細かなコマンド周りで知見を汲み取ってもらえると...!!あとは... 程々に元気です。制作頑張ります。
-
リソースパックを用いて任意の文字にアイコンを割り当てすることができる技術。私作のこちらの渾身の動画を参考にしてください。https://youtu.be/w0Zraz-o8yE?si=51rLwk7WKMKl3iUI ↩
-
表示するアイコンの中に描画するピクセルが存在しない場合、右側の空白に限り自動的に左に詰められます。この仕様を用いることで、縦横サイズの統一をしていないアイコンを一つの画像で割り当てできるので、何かと活用することがあります(後述のui_text.pngにて活用しています)。 ↩
-
\uE301~\uE380などと割り当てをした場合、マクロで下2桁を設定する際に01~80を入力する必要性が出てくるため、純粋に数値を入力するだけでは
\uE31などといった存在しないテキストを出力しようとしてしまい、特定の場合でエラーが起きてしまう。 ↩ -
こちらの動画。渾身です。https://youtu.be/Dtn_FQcDF8E?si=aIPJHBbUf9UmJg4a ↩