【メモ】UIをいじるコツ

[!] "ガチモン"のメモ(備忘録)なので、雑です。それでもよければ参考にしてみてください。


 HUDにテキストや画像、ボタンを追加する例

▶ (リソース)/ui/hud_screen.json と (リソース)/ui/chat_screen.json を主に使用

■ 大元をとらえる

 大元──絵を描く例えならキャンバスのような部分が示されている場所を探す。
 chat_screen.json(以下、"チャットjson")ならばコメントアウトで分かりやすく「MainScreen」と書いてある(ℓ592)がhud_screen.json(以下、"HUDjson")ではそうもいかず、書いてくれない。チャットjsonがそうだったようにある程度下の方に置いてあるのかなとアタリをつけて探してみると、それっぽいもの:"hud_content" が見つかる(ℓ2155)。実際これが「大元」であるキャンバスになる。

 これからは主にHUDjsonで話を進めていく。

■ 子要素をぶら下げる

 "hud_content" の "controls" へ目を向けると、どうやらそこにオブジェクトが並んでいる。これが子要素の指定だ。
 ここに、以下のように子要素を追加してみる。

"controls": [
 {
  "root_panel@hud.root_panel": {}
 },
 { "test@hud.test": {} },
 { "test2@hud.test2": {} },
 { "test3@hud.test3": {} },
 {
  "camera_renderer@camera_renderer": {}
 },
 { "inventory_selected_icon_button@common.inventory_selected_icon_button": {} }
]

 子要素の指定方法の前に見ておくべきものがある。jsonのいちばん上に行くと、"namespace" なる要素があり、これに連なる値がそのjsonのidとなる。「minecraft:hud」と書いてあるようなもの。そしてこれを今後は "jsonのid" と呼ぶ。HUDjsonなら "hud" となっているはず。
 @の左は自由に決められるid@の右はその子要素が存在するjsonのid、ピリオドを挟んで子要素の名前になる。子要素の名前は@の左のidとカブらせられるので是非カブらせておくといい。そのほうが分かりやすいし、命名に悩まなくて済む。

■ テキストを表示する

 まずは子要素 "test" から。"hud_content" と並列して "test" を次のように置く。
 コピーするならチャットjsonのℓ509にあるそっくりなコードを使った方がいい。現に、以下のコードはそれを改造したものだし、それとは別にこの記事のコードには見やすさのためにほとんど全角スペースが使ってある
(「ℓ」の意味はわかってほしい、「low(行)」の頭文字であるLの小文字の筆記体だ。つまり行数を示す)

"test": {
 "type": "panel",
 "size": [ "100%", "100%" ],
 "controls": [
  {
   "title_panel": {
    "type": "label",
    "anchor_to": "top_right",
    "anchor_from": "top_right",
    "size": [ "default", 10 ],
    "text": "AnyText",
    "color": "$title_text_color",
    "layer": 2,
    "shadow": true
   }
  }
 ]
},

 実はテキスト単体を示すコードではない。HTMLで言うところのdivのなかにテキストがあるコードだ。こうするとなにかしらのいいことがあるんだろうと思ってもらえればいい。このコードには "type" が二つあることに気づくと思うが、外側は "panel" となっており、これがdivみたいなものを意味する"label" のほうこそがテキストであることを示す
 もしかしたらlabelはなくてもたいして変わらないかもしれない。

■ anchor_to, anchor_from

 「どこ寄せ」にするか。toとfromの二種類が存在する意味はまだ理解していない。毎度両方書くのが無難だろう
 全部見たことがある訳ではないが、top_rightで右上、top_leftで左上、bottom_right, bottom_leftで右下/左下、right_middle, left_middleで右中央/左中央
 中央に置きたい場合はこの要素は両方消してよい

■ size

 縦横の大きさ。二つあるが上の方は変えなくてよい。数字単体ならpxで指定(おそらく)、「""」でくくって%で指定すると画面に対する割合で大きさを選べる。

■ text

 表示するテキスト「§」を使って色を変えられる。また、langIDを書けば.langファイルで変えられる。言語ごとに自動でテキストを入れ換えられるのがメリット(/titlerawコマンドで似たようなことは可能)

■ color

 テキストの色。「$title_text_color」というのは(リソース)/ui/_global_variables.json のℓ35で定義されているテキストの色。独自に指定したいなら「 [ 1.0, 1.0, 1.0 ] 」というように小数のアレイでRGBを指定できる。それぞれの値は0.0から1.0しかとれないはず。

■ layer

 レイヤー。

■ offset

 ここにはないが [ a, b ] で指定できる右と下が+でその値だけ位置をずらすことができる。もしかしたら「どこ寄せ」によって変わるかもしれないので自分でいろいろ試してみるといいだろう。

■ shadow

 テキストに影をつけるかどうか。ちなみにプレイ画面左上の座標テキストは影あり、/titleなどでアクションバーに表示されるテキストは影なし。

■ 画像を表示する

 このコードはチャットjsonのℓ16を改造したコード。周囲の似たコードなら正直どれでもいい。

"test2": {
 "type": "image",
 "size": [ 52, 52 ],
 "texture": "textures/ui/gear",
 "offset": [ -100, -30 ]
},

 テキストの場合とだいたいできることは変わらない。この場合offsetがどちらも負なので画面の中心から右上あたりに表示される。

■ texture

 表示する画像のテクスチャのファイルパスを指定する

■ ボタンを置く

 こちらはチャットjsonのℓ135に似たものがあるが、それを書き換えて作ったものではなく、いろいろ変わってるので全角スペースに注意できるならコピーしたほうがいいだろう。

"test3@common_buttons.light_content_button": {
 "$button_content": "hud.test4",
 "size": [ 50, 50 ],
 "offset": [ 0, 0 ],
 "$pressed_button_name": "button.hotbar_inventory_button"
},

 test4はここまでで一切登場していないが、いちおう実験に使ったのは以下のコードである。とくに紹介してないことはしていない。

"test4": {
 "type": "label",
 "size": [ "default", 10 ],
 "text": "TEXT",
 "color": [ 0, 0, 0 ],
 "shadow": true
},

 そしてボタンも同様にanchorやoffset、sizeなど使えそうなものは使える

■ $button_content

 ボタンの上にテキストまたは画像を置くために、テキストや画像の子要素を指定する。テキストを指定するときには、はじめに説明したようにlabelの中に入れる必要はない

■ $pressed_button_name

 押したときのボタンイベントを指定する。しかし、同じ画面(json)に存在するボタンの効能しか割り当てられないため何も面白いことはない。ということでそもそもボタンを追加する意味がなくなった。
 同じjsonのなかで「$pressed_button_name」を探して「button.」で始まっている指定をコピーしてペーストするとよい。ちなみに「button.hotbar_inventory_button」はHUDjsonのℓ349にある、イベントリを開くという機能をもったものである。

 これで以上。これだけでも大分UIのjsonが読みやすくなったのではないだろうか。

■メモ - Schema

"button"
  "always_handle_pointer": bool
  "default_control": [ "default" ]
  "default_focus_precedence": int
  "focus_change_down": str
  "focus_change_left": str
  "focus_change_up": str
  "focus_change_right": str
  "focus_enabled": bool
  "focus_identifier": str
  "focus_magnet_enabled": bool
  "focus_wrap_enabled": bool
  "follows_cursor": bool
  "hover_control": [ "hover" ]
  "locked_control": [ "", "locked" ]
  "pressed_control": [ "pressed" ]
  "sound_name": str[ "random.click" ]
  "sound_pitch": float
  "sound_volume": float
  "tts_control_header": str
  "tts_control_type_order_priority": int
  "tts_index_priority": int
  "tts_name": str
  "tts_section_header": str
  "visible": bool
  
  "anchor_to": Pos
  "anchor_from": Pos
  "bindings": [ obj* ]
  "button_mappings": [ obj* ]
  "controls": [ obj* ]
  "layer": int
  "offset": [ float, float ]
  "size": [ int, int ]

"custom"
  "animation_reset_name": [ "screen_animation_reset" ]
  "renderer": [ "hud_player_renderer" ]
  
  "anims": [ anims-Ref* ]
  "bindings": [ obj* ]
  "controls": [ obj* ]
  "layer": int
  "size": [ int, int ]

"edit_box"
  "constrain_to_rect": bool
  "enabled": #Ref
  "enabled_newline": bool
  "default_control": [ "default" ]
  "focus_change_down": str
  "focus_change_left": str
  "focus_change_right": str
  "focus_change_up": str
  "focus_enabled": bool
  "focus_identifier": str
  "hover_control": [ "hover" ]
  "locked_control": [ "locked" ]
  "max_length": int
  "pressed_control": [ "pressed" ]
  "text_box_name": #Ref
  "text_edit_box_grid_collection_name": str
  "text_type": [ "ExtendedASCII" ]
  "tts_control_header": str
  "tts_name": str
  "tts_override_control_value": str
  "tts_section_header": str
  
  "anchor_from": Pos
  "anchor_to": Pos
  "button_mappings": [ obj* ]
  "layer": int

"factory"
  "control_ids": {
    str: Ref
  }
  "control_name": Ref
  "name": str
  
  "size": [ int, int ]

"grid"
  "collection_name": str[ "hotbar_items", "inventory_items" ]
  "grid_dimensions": [ int, int ]
  "grid_dimension_binding": #Ref
  "grid_fill_direction": [ "vertical" ]
  "grid_item_template": Ref
  
  "anchor_to": Pos
  "anchor_from": Pos
  "size": [ Size, Size ]

"image"
  "alpha": float
  "animation_reset_name": str[ "screen_animation_reset" ]
  "bilinear": bool
  "clip_direction": [ "left" ]
  "clip_pixelperfect": bool
  "color": [ float, float, float ]
  "disable_anim_fast_forward": bool
  "ignored": bool
  "texture": str
  "tiled": bool, str[ "x", "y" ]
  "uv": anims-uv-Ref*
  "uv_size": [ int, int ]
  "visible": bool
  
  "anims": [ anims-Ref* ]
  "bindings": [ obj* ]
  "controls": [ obj* ]
  "layer": int
  "offset": [ float, float ]
  "size": [ Size, Size ]

"input_panel"
  "focus_container": bool
  "hover_enabled": bool
  "prevent_touch_input": bool
  "ttsSectionContainer": bool
  "use_last_focus": bool
  
  "anchor_from": Pos
  "anchor_to": Pos
  "button_mappings": [ obj ]
  "controls": [ obj* ]
  "layer": int
  "size": [ Size, Size ]
  "variables": [ obj* ]

"label"
  "alpha": float
  "color": [ float, float, float ]
  "enable_profanity_filter": bool
  "font_scale_factor"
  "font_size": [ "extra_large", "large", "normal" ]
  "font_type": [ "smooth" ]
  "line_padding"
  "localize": bool
  "locked_alpha": float
  "locked_color": [ float, float, float, float ]
  "max_size": [ Size, Size ]
  "shadow": bool
  "text": str
  "text_alignment": Pos
  "tts_name": str
  
  "anchor_from": Pos
  "anchor_to": Pos
  "anims": [ anims-Ref* ]
  "bindings": [ obj* ]
  "layer": int
  "offset": [ float, float ]
  "size": [ Size, Size ]
  "variables": [ obj* ]

"panel"
  "factory": {
    "control_ids": {
      str: Ref
    }
    "max_children_size": int
    "name": str
  }
  "ignored": bool
  "max_size": [ Size, Size ]
  "min_size": [ Size, Size ]
  
  "anchor_from": Pos
  "anchor_to": Pos
  "bindings": [ obj* ]
  "controls": [ obj* ]
  "layer": int
  "offset": [ float, float ]
  "size": [ Size, Size ]
  "variables": [ obj* ]

"screen"
  "absorbs_input": bool
  "always_accepts_input": bool
  "button_mappings": [ obj ]
  "cache_screen": bool
  "close_on_player_hurt": bool
  "force_render_below": bool
  "gamepad_cursor": bool
  "is_modal": bool
  "is_showing_menu": bool
  "low_frequency_rendering": bool
  "render_only_when_topmost": bool
  "render_game_behind": bool
  "screen_draws_last": bool
  "screen_not_flushable": bool
  "send_telemetry": bool
  "should_steal_mouse": bool
  "vr_mode": $Ref
  
  "controls": [ obj* ]

"selection_wheel"
  "button_name": ButtonFunc
  "default_focus_precedence": int
  "focus_enabled": bool
  "inner_radius": float
  "iterate_left_button_name": ButtonFunc
  "iterate_right_button_name": ButtonFunc
  "outer_radius": float
  "slice_count": int
  "sound_name": str[ "random.click" ]
  "sound_pitch": float
  "sound_volume": float
  "state_controls": [ ]
  "tts_name": str
  "tts_control_header": str
  "tts_section_header": str
  "tts_control_type_order_priority": int
  
  "button_mappings": [ obj* ]
  "layer": int

"stack_panel"
  "collection_name": Ref
  "factory": {
    "control_ids": {
      str: Ref
    }
    "max_children_size": int
    "name": str
  }
  "min_size": [ Size, Size ]
  "orientation": [ "horizontal", "vertical" ]
  "propagate_alpha": bool
  
  "anchor_from": Pos
  "anchor_to": Pos
  "bindings": [ obj* ]
  "controls": [ obj* ]
  "offset": [ float, float ]

Size
  int
  fill
  default
  %c
  %y
  px
  %cm
  %sm
  +
  -

Pos
  top_middle
  bottom_middle
  top_left
  center
  right
  left_middle
  left
  top_right

*anims-Ref
  "anim_type": [ "uv", "offset", "alpha", "wait", "flip_book", "size" ]
  "destroy_at_end": [ "chat_grid_item" ]
  "duration": int
  "easing": [ "linear", "in_quart", "in_expo", "out_cubic", "out_back" ]
  "end_event": Ref
  "from": float, [ int, int ]
  "next": anims-Ref*
  "play_event": Ref
  "reset_event": str[ "screen_animation_reset" ]
  "resettable": bool
  "to": float, [ Size, Size ]

*anims-uv-Ref
  "anim_type": [ "flip_book" ]
  "easing": [ "linear", "in_quart", "in_expo", "out_cubic", "out_back" ]
  "fps": int
  "frame_count": int
  "frame_step": int
  "initial_uv": [ int, int ]
  "reversible": bool

*bindings
  "binding_collection_name": $Ref, str[ "chat_text_grid", "boss_bars" ]
  "binding_condition": [ "always_when_visible", "always", "once" ]
  "binding_name": $Ref, #Ref
  "binding_name_override": #Ref
  "binding_type": [ "global", "collection_details", "collection" ]

*button_mappings
  "consume_event": bool
  "from_button_id": ButtonFunc
  "handle_select": bool
  "handle_deselect": bool
  "to_button_id": $Ref
  "mapping_type": [ "pressed", "focused", "global" ]

*controls
  Ref: {}

*variables
  "requires": $Ref

MinecraftBEアドオン-ヒント倉庫

MimecraftBEのアドオン作りで困ったときにここで解決できるようにと個人によって作られたものです

1コメント

  • 1000 / 1000

  • Sou swim924

    2021.12.29 07:07

    ここで例として見ているファイルってありますか? 回答のほどよろしくお願いいたします。