Molangとは

「Molang」と聞くと、難しそうと感じる人も少なくないと思います。この記事では、Molangについて特別な知識がなくてもできるだけわかりやすいように書いてあります。また、すべての知識を一度に覚えるよりもまずはどんなことができるのかを確認し、その後、Molangを実際に使う場面でこの記事を参考にしてもらえるとMolangの学習速度が上がると思います。

Molangとは

そもそも、Molang(MoLangと表記される場合もあります)とはマイクラ統合版で使用されているスクリプト言語です。基本的には、JSONの構文の中に短く(1,2行程度)記述することがほとんどです。

ではなぜ、JSONではなく、Molangを使って書くのでしょうか?

それは、それぞれでできることが異なるからです。JSONはブロックやアイテム、エンティティなどの基本的な情報をあらかじめ決めておくためのものです。例えば、ブロックのテクスチャや当たり判定の大きさを設定したり、エンティティの体力や移動速度を設定したりします。

このように、JSONでは決まった情報を設定するのが主な役割です。しかし、JSONだけではゲーム内で起こる出来事によって、動作を変化させることができません。

ここで、使えるのがMolangです。MolangはJSONの中に短い命令のようにして書き加えることで、ゲーム内で起こることに合わせて動作を変化させることができます。例えば、エンティティがダメージを受けて体力が減っていると、見た目を変えたり、プレイヤーが向いている向きに応じて、ブロックの見た目を変えたりすることができます。

これだけではなく、さらに計算を行うこともできます。基本的な四則演算はもちろん、平方根や三角関数など複雑な計算もすることができます。この辺りは、エンティティのアニメーションに使ったり、パーティクルを動かすのに使うことが多いです。

以下の動画はブロックのJSON内にMolangを使用して、条件に応じて動作を変更しています。

この動画のブロックでは、プレイヤーの視線の先がブロックの上半分の場合はハーフブロックを上側に置き、視線の先がブロックの下半分の場合はハーフブロックを下側に置くように作ってあります。

以下のjsonコードは上記の動画のブロックの動作が書かれている部分を抜粋したものです。

"permutations": [
    {
        "condition": "q.block_state('minecraft:vertical_half') == 'top'",
        "components": {
            "minecraft:geometry": "geometry.half_block_top",
            "minecraft:collision_box": {
                "origin": [ -8, 8, -8 ],
                "size": [ 16, 8, 16 ]
            },
            "minecraft:selection_box": {
                "origin": [ -8, 8, -8 ],
                "size": [ 16, 8, 16 ]
            }
        }
    },
    {
        "condition": "q.block_state('minecraft:vertical_half') == 'bottom'",
        "components": {
            "minecraft:geometry": "geometry.half_block_bottom",
            "minecraft:collision_box": {
                "origin": [ -8, 0, -8 ],
                "size": [ 16, 8, 16 ]
            },
            "minecraft:selection_box": {
                "origin": [ -8, 0, -8 ],
                "size": [ 16, 8, 16 ]
            }
        }
    }
]

“condition”の後にある”q.○○”と書かれているのがMolangです。

このように、Molangを使うことによって固定された情報だけでなく、ゲーム内の状態によって処理を変えることができるようになります。

molangの変数

変数というのは値を入れておく箱のようなものです。マイクラの中ではチェストのようなものです。そして、この変数には必ず名前を付けてあげないといけません。名前がないとなんの箱なのかわからなかったり、他の変数との違いがわからなかったりします。

さらに、マイクラのチェストは用途によって色々な種類がありますよね?それと同じように変数にも用途によって複数の種類があるので適切に使い分けないと、うまく動かなくなります。

まず、変数は2種類の使い方をします。1つ目は書き込みです。変数を使う前に必ず、変数の名前を決めて、その変数の中に入れる値を指定します。2つ目の使い方は読み込みです。書き込んだ変数を他の場所で計算に使ったり、条件に使ったりします。これを頭の隅のほうに置いといたうえで、変数の種類について話します。

Molangの変数には一時変数、エンティティ変数、コンテキスト変数の3種類あります。

一時変数(temp)

一時変数は一時的に使う変数です。大きな特徴として、一時変数は定義されたスコープ内でのみ変数を書き込んだり、読み込んだりすることができます。あまり使う必要がない変数なので慣れないうちは使わなくて大丈夫です。

// 書き方は以下の通り .の後ろは好き名前にできる
temp.xxx

// 書き方を省略することもでき、一時変数の場合は以下の通り
t.xxx

エンティティ変数(variable)

エンティティ変数はそのエンティティが生きている間(スポーンしている間)そのエンティティに値を保存します。エンティティが死んだり、消えたりした場合はもちろん、ワールドを閉じても値はリセットされます。一番使いやすい変数なのでこの変数をよく使用します。

// 書き方は以下の通り .の後ろは好き名前にできる
variable.yyy

// 書き方を省略することもでき、エンティティ変数の場合は以下の通り
v.yyy

コンテキスト変数(context)

コンテキスト変数は一度、変数を宣言すると、それ以降は書き込むことができない変数です。こちらもあまり使うことはないと思います。

// 書き方は以下の通り .の後ろは好き名前にできる
context.zzz

// 書き方を省略することもでき、コンテキスト変数の場合は以下の通り
c.zzz

Molangの書き方

Molang式の最後にはセミコロン(;)を付けます。これは、複数の式の計算を行う際に、どこまでが一つの計算なのかを区別するために用います。式が一つの場合は省くことができます。

"temp.x = 1 + 1; temp.x * 10;"   // 複数の式がある場合はこのように必ず、;を付ける
"temp.y = 10 / 5"   // 式が1つの場合は;を省略することができる

関係演算子

関係演算子とは、2つの値を比較して、その関係が正しい(真)か誤っている(偽)かを判断するための記号です。多くのプログラミング言語では、真をtrue、偽をfalseとして表現しますが、molangでは、真を1.0、偽を0.0として表現します。

等しい(==)

左辺の値と右辺の値が等しいかどうかです。等しい場合は真である1.0を出力し、等しくない場合は偽である0.0を出力します。

"temp.x == 5"   // temp.xが5であるかどうか

等しくない(!=)

左辺の値と右辺の値が等しくないかどうかです。先ほどの「==」の反対です。

"temp.x != 5"   // temp.xが5でないかどうか

より大きい(>)

左辺の値が右辺の値と比べて大きいかどうかです。

"temp.x > 5"   // temp.xが5よりも大きいかどうか

以上(>=)

左辺の値が右辺の値と比べて大きいもしくは等しいかどうかです。

"temp.x >= 5"   // temp.xが5以上かどうか

より小さい(<)

左辺の値が右辺の値と比べて小さいかどうかです。

"temp.x < 5"   // temp.xが5よりも小さいかどうか

以下(<=)

左辺の値が右辺の値と比べて小さいもしくは等しいかどうかです。

"temp.x <= 5"   // temp.xが5以下かどうか

論理演算子

さらに複雑な条件を作るときに使用する演算子です。関係演算子だけでは一つの条件しか使えませんが、論理演算子を挟むことにより、複数の条件を組み合わせられるようになります。

AND(&&)

この演算子の前後にある条件がそれぞれ真になったときに全体が真になり、それ以外の場合は偽になります。

"temp.x == 5 && temp.y == 10"   // temp.xが5であるかつtemp.yが10であると真

OR(||)

この演算子の前後にある条件のどちらか一つでも真があれば、全体が真になります。

"temp.x == 5 || temp.y == 10"   // temp.xが5もしくはtemp.yのどちらかが真であれば、真

NOT(!)

この演算子は結果の前に使います。これを使うことにより、結果を反転することができます。条件の結果が真の場合は偽になり、偽の場合は真になります。

"!(temp.x == 5)"   // temp.xが5ではないと真

簡単な計算

Molangでは計算をすることもできます。書き方はプログラミング言語とほとんど同じです。ここは難しくないのでまとめて紹介します。

// 足し算
"temp.x = 10 + 5"   // temp.xは15になる

// 引き算
"temp.x = 10 - 5"   // temp.xは5になる

// 掛け算
"temp.x = 10 * 5"   // temp.xは50になる

// 割り算
"temp.x = 10 / 5"   // temp.xは2になる

もちろん一つの式の中に足し算や引き算などを混ぜることもできます。その場合は、掛け算や割り算が優先されて計算されます。もし、足し算や引き算を優先して計算したい場合は()を付けることで優先させることができます。

"temp.x = 10 + 5 * 4"   // temp.xは30になる

"temp.x = (10 + 5) * 4"   // temp.xは60になる

三項演算子とnull合体演算子

名前が難しそうに感じますが、実際に使ってみるとそこまで複雑ではないので安心してください。

三項演算子(? :)

三項演算子は一つの式の中に条件の式と真の場合の処理、偽の場合の処理の三つを含めたものです。

// 条件の式 ? 真の場合の処理 : 偽の場合の処理
"temp.x == 0 ? temp.x = 1 : temp.x = 0"

null合体演算子(??)

null合体演算子は評価したい値が有効な値であればその値を使い、もし有効ではない値の場合、指定した値を使うというものです。

以下のサンプルの式では、temp.xに値がすでに入っていればその値を使いますが、temp.xの値をまだ決めていない場合は2にして計算するという意味です。

"temp.x = (temp.x ?? 2) + 4"
// temp.xに3が入っていれば、値は3+4で7になります。
// temp.xに値が入っていない場合、値は2+4で6になります。

さて、ここまではMolangを使ってなにか計算をさせるときによく使うものや条件分けに関する基本的なものを取り上げました。

クエリ関数

クエリ関数はゲームに対して、欲しい情報を「質問」として投げかけて、その「答え」を数値や文字列として受け取るための機能です。

例えば、

  • このモブは、今地面にいるのか?
  • プレイヤーがスニークしているのか?

などの質問をし、この答えを利用して、エンティティのアニメーションを変えたり、テクスチャを変えたりすることができます。

クエリ関数の書き方

クエリ関数は、query. または省略形の q. から始まります。

query.質問内容
q.質問内容

利用可能なクエリ関数はアップデートで追加されていき、かなり多くの種類があるためここではよく使われるものを抜粋して紹介します。すべてのクエリ関数は以下の公式のドキュメントを参考にすることをおすすめします。

Molang Query Functions Documentation - Molang Query Functions
A reference document describing all current Molang Query Functions

よく使われるクエリ関数

クエリ関数名説明主な用途
query.anim_timeアニメーションが再生されてからの時間。アニメーション
query.life_timeエンティティがスポーンしてからの経過時間。エンティティ
query.is_on_groundエンティティが地面に足をつけているかどうか。エンティティ
query.is_in_waterエンティティが水中にいるかどうか。エンティティ
query.is_movingエンティティが移動しているかどうか。エンティティ
query.healthエンティティの現在の体力値。エンティティ
query.is_babyエンティティが子供状態かどうか。エンティティ
query.variantエンティティのバリアント(種類)の番号。例:村人の職業や猫などに使われています。エンティティ
q.block_state(‘minecraft:vertical_half’)視線がブロックの上半分もしくは下半分のどちらにあるか。ブロック
query.is_item_name_any(‘item_name’)手に持っているアイテムが指定した名前かどうか。アイテム
query.is_using_itemアイテムを使用中(右クリック長押し)かどうか。アイテム

数学関数

数学関数(math関数)は複雑な計算を行いたいときに使います。例えば、アニメーションを作成するときにボーンの回転を四則演算だけでは難しいときなどに利用します。

名前の通り、数学の知識が必要なものもあるため、ここではすべてを紹介しませんが、以下の公式のドキュメントを参考にすることをおすすめします。

Molang Documentation - Introduction to Molang
A reference document introducing the concept of Molang to creators

math.sin(値)

この関数は波のような滑らかな動きを簡単に作るための関数です。mth.sin(x) のような形で書き、xの部分に角度(0~360°)が入ります。

以下はmath.sin(x)をグラフにしたものです。

math.pow(底, 指数)

この関数はべき乗と言われるものです。2の3乗とかですね。

以下はmath.pow(2, x)をグラフにしたものです。

math.sqrt(値)

平方根です。√2とかですね。

以下はmath.sqrt(x)をグラフにしたものです。

math.random(最小値, 最大値)

最小値と最大値の間のランダムな小数を返します。
※ランダムな整数を使いたい場合はmath.random_integer(最小値, 最大値)とすると、整数値を返してくれます。

他にも多くの数学関数があるので、気になる方は先ほど紹介した公式のドキュメントに目を通してみてください。

実例

実際にMolangを使用している記事を紹介します。

ブロック関連

ブロックの向きを設定する際にクエリ関数を使用しています。

ブロックを置くときのプレイヤーの視線の先の場所に応じて、動作を変える際にクエリ関数を使用しています。

アイテム関連

3Dアイテムの帽子のモデルファイル内でバインディングさせる際に、クエリ関数を使用しています。

まとめ

このページを読めば、Molangを知らないひとでも、なんとなくMolangがどういうものかイメージできるようになったと思います。ただ、Molangを実際にどの場面で書くのかを説明するとかなりのボリュームになってしまうので省きましたが、アニメーションやパーティクル、エンティティの作成などでMolangを書く場面が出てきたときに、この記事を参考にして学んでもらえれば幸いです。

コメント

コメント通報