【入門者・初心者向け】MEL基礎

ツール開発未経験だけどとりあえずmelの書き方を知りたい、
非エンジニアがmelを書いたっていいじゃない、
そんな方向けのmelの入門者向け基礎知識になります。

##スクリプトの置き場所
`/Documents/maya/scripts/AAA.mel`
又は
`/Documents/maya/(mayaVer.)/scripts/AAA.mel`(英語)
`/Documents/maya/(mayaVer.)/ja_JP/scripts/AAA.mel`(日本語)
(置いた後実行するにはmelファイルをmayaのビューにそのままドラッグするか、再起動が必要です。)
##スクリプトの実行方法
コマンドライン、スクリプトエディタから、またはシェルフに登録して実行します。
![Exsample_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511509/7de5925a-a00e-0287-923b-f3250bd63bd2.png)
AAA.melという名前のmelを実行する場合

```mel:MayaConsole
AAA;
```
#コーディングソフト
VScodeをインストールします、
melが書けるコーディングソフトが無料で使用できます。
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
![Exsample_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511509/fcb7c9ba-12ed-568f-d61c-16a2db772735.png)
![Exsample_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511509/e58d4035-4c78-fe0b-8749-fc8d7d6b9536.png)
※スクリプトエディタでコーディングはしません、スクリプトの起動やちょっとしたコードなら書いたりしますが、mayaが落ちると書き途中のコードも道連れにしてしまうのでオススメしません。(経験ある方ならわかると思いますがmaya、結構落ちます。)
![Exsample_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511509/8cf92588-0a24-d6f1-65b3-086748092a5b.png)
##スクリプトのリロード

スクリプトを編集しても変更はmayaに反映されないので、以下の方法でリロードする必要があります。
・mayaを再起動する。
・スクリプトファイルをmayaのビューポートへドラッグ＆ドロップ。
・"source"でファイルを指定してリロード。

###sourceによるリロ-ド

```mel:MayaConsole
source "C:/Users/pc/Documents/maya/scripts/AAA.mel";
AAA;
```
(拡張子.melは省略可能です。)
("\" は認識しません、"/"と書きます。)
(状況によってローカルパス、相対パス、絶対パスを指定します)
(※"pc"には自分のPC名を入れて下さい)
##mel作法
####"ファイル名とグローバル関数名は同じ名前にする。"
melファイルを読んだときに自動でファイル名と同じ名前のグローバル関数が読まれるので同じ名前にしておく必要があります。
####"関数名はできるだけglobal procではなくprocを使う"
"proc"はローカル名でファイル内のみで有効なので問題ありませんが、
不用意にグローバル名を増やすと関数名による競合が起きやすくなるのでできるだけprocで済ませた方が安全です。
##書いてみる
mayaスクリプトエディタ(MayaConsole)からAAA.melを実行してヒストリーウィンドウに"Hello_AAA"と表示します。

```mel:AAA.mel
global proc AAA(){
    print "Hello_AAA";
}
```
```mel:MayaConsole
source "AAA";
AAA();
```
`Hello_AAA`
##"globalproc"と"proc"
以下は"AAA"が同じファイル内の"TestProc"を呼び出しています。
外部から呼び出すプロシージャは"global proc"である必要がありますが、
以下のように呼び出し元と呼び出し先が同じファイル内にあればprocで問題ありません。

```mel:AAA.mel
proc TestProc(){
    print "Hello_AAA";
}
global proc AAA(){
    TestProc;
}
```
`Hello_AAA`
##実行したプロシージャから別のプロシージャを呼び出す
ランチャーからスクリプトを呼び出したり、使い回しできるように処理を分けたり、
スクリプトからスクリプトを呼び出したいときがあります、以下はAAAファイルからBBBファイルを呼び出しています、外部から呼び出すためglobal procを使用します。
(sourceでBBBをリロードしていますがBBBに変更がなければ必要ありません)

```mel:BBB.mel
global proc BBB(){
    print "Hello_BBB";
}
```
```mel:AAA.mel
global proc AAA(){
    source "C:/Users/pc/Documents/maya/scripts/BBB";
    BBB;
}
```
`Hello_BBB`
##値を渡す
別のプロシージャを呼び出すときに、現在のプロシージャから変数を渡す事ができます。
以下は、"Hello"と"World"が入った変数ををBBBに渡してprintしています。

```mel:BBB.mel
global proc BBB(string $Word_0,string $Word_1){
    print $Word_0;
    print $Word_1;
}
```
```mel:AAA.mel
global proc AAA(){
    string $Word_0 = "Hello";
    string $Word_1 = "World";
    $Word = BBB($Word_0,$Word_1);
}
```
`Hello`
`World`
##値を返す
実行したスクリプトに引数を渡して値を受け取る事ができます。
以下は、文字列"Hello"が入った変数$WordをAAAからBBBに渡して"HelloMel"に変更して再びAAAに戻してprintしています。
文字列を返すプロシージャは"global proc string"と書くことによって変数をreturnできます。

```mel:BBB.mel
global proc string BBB(string $Word){
    $Word = $Word + "Mel";
    return $Word;
}
```
```mel:AAA.mel
global proc AAA(){
    string $Word = "Hello";
    $Word = BBB($Word);
    print $Word;
}
```
`HelloMel`
配列も同じように返すことができます。
返す型に合わせて"global proc string[]"と書きます。

```mel:BBB.mel
global proc string[] BBB(string $Word[]){
    $Word[0] = $Word[0] + "Mel";
    $Word[1] = $Word[1] + "Maya";
    return $Word;
}
```
```mel:AAA.mel
global proc AAA(){
    string $Word[] = {"Hello","Happy"};
    $Word = BBB($Word);
    print $Word;
}
```
`HelloMel`
`HappyMaya`