以前紹介した MELの多言語対応 で使用していたのは、uiResコマンドと displayStringが羅列された .res.melファイルだったのですが、ふと、mayaのUIで日本語訳を調べるために .res.melファイルを検索してみたのですが、全くと言って良いほどヒットしなくなっていました。
どうやら最近は、uiResコマンドや .res.melファイルではなく、setPluginResourceコマンドと .pres.melファイルを使用するように変わっているようです。
なので、さっそくMELコマンドのテクニカルドキュメントを見てみることにしました。
見慣れない resource関係のコマンドが幾つか見つかりました。
とりあえず setPluginResourceコマンドの概要を読んでみると、registerPluginResource、loadPluginLanguageResources、getPluginResourceも関係している必要なコマンドのようです。ですが、予備知識もなく各コマンドの概要を読んでみてもパッとしません。
そこで、c:\Program
Files\Autodesk内をアサってみます。
どうやら、registerPluginResourcesコマンドで登録し、loadPluginLanguageResourcesコマンド内の
setPluginResourceコマンドでローカライズ版をオーバーライド。
ラベル作成時に
getPluginResourceコマンドを使用するみたいです。
そして、MELコマンドのテクニカルドキュメントには書かれていませんが、~InitStrings.melという初期化スクリプトを起点にローカライズを行っているように見えます。
とりあえず、sampleInitStrings.melと sample.melを作って動作を確認してみます。
まずは初期化スクリプト
global proc sampleInitStrings()
{
// Register script resources
registerPluginResource("sample","kSampleMenu","Sample Menu");
// Load any localized resources
loadPluginLanguageResources("sample","sample.pres.mel");
}
ここで、毎度のことながら loadPluginLanguageResourcesが ja_JPフォルダを探すところでエラーが出てしまうので、さくっとスクリプトを自作します。
proc string _getLanguageResourcePath(
string $file )
{
string $name = python("'"+$file+"'[:-9]");
string $script =`whatIs $name`;
if("Unknown"==$script) return "";
string $tmp[]= python("'"+$script+"'.split(' ')");
string $dir = dirname($tmp[size($tmp)-1]);
string $ull =`about -ull`;
string $resFile = ($dir+"/"+$ull+"/"+$file);
if(`filetest -f $resFile`) return $resFile;
return "";
}
global proc tryLoadLanguageResources(
string $resFile )
{
if( !`about -uii`) return;
string $languagePath = _getLanguageResourcePath( $resFile );
if(""!=$languagePath)
{
eval("source \""+ $languagePath+"\"");
}
}
sampleInitStrings.melの7行目を
tryLoadLanguageResources("sample.pres.mel");
のように変えます。sample.melと同じフォルダに在る ja_JPフォルダを探して、その中の sample.pres.melを実行し見つからなければ何もしません。
次に前回と同様、メニューを作成するスクリプトでテストしてみます。
sampleInitStrings();
global proc sample()
{
global string $gMainWindow;
if( ""==$gMainWindow || !`window -ex $gMainWindow`) return;
// 旧メニュー削除
string $menu="sampleMenu_in_mainMenu";
if(`menu -q -ex $menu`) deleteUI $menu;/* for debug. */
// メニュー作成
setParent $gMainWindow;
menu -p $gMainWindow -l (getPluginResource("sample","kSampleMenu")) $menu;
}
1行目で初期化スクリプトを実行しようとしていますが、sampleコマンドを実行しても、この部分はメインプロシージャの外側なので実行されません。なので、この sample.melを正しく動作させるには
source "sample.mel"; sample;
と、sourceコマンドを挟む必要があります。
ただ、自作スクリプトを作成している途中で初期化スクリプトを実行してしまうと
registerPluginResourceコマンドの実行で警告が出てしまうので、displayString -deleteを使うように工夫する必要があるかもしれません。
裏で警告が出ているのが気持ち悪いですが、
global proc sample()
{
global string $gMainWindow;
if( ""==$gMainWindow || !`window -ex $gMainWindow`) return;
// 初期化
catchQuiet(`sampleInitStrings`);
// 旧メニュー削除
string $menu="sampleMenu_in_mainMenu";
if(`menu -q -ex $menu`) deleteUI $menu;/* for debug. */
// メニュー作成
setParent $gMainWindow;
menu -p $gMainWindow -l (getPluginResource("sample","kSampleMenu")) $menu;
}
と、7行目のようにメインプロシージャ内に入れ込んでしまっても良いかもしれません。
そして15行目が getPluginResourceコマンドでラベルを取得している部分です。
最後に、.pres.melの作成について。
本来なら pluginResourceUtilコマンドを使うことで、簡単に雛形を作成できるみたいなのですが、プラグインがロードされている事が前提になっているため、MELスクリプトだけの場合では、実行しても普通にエラーで停止してしまいます。
なので必要な部分だけ抜き出して自作します。
proc printResourceString(
string $name
,string $id
,string $value)
{
string $fmt ="setPluginResource(\"^1s\",\"^2s\",\"^3s\");\n";
print(`format -s $name -s $id -s $value $fmt`);
}
global proc tryGeneratePres(string $name)
{
if(`about -uii`) error -n "uiLanguage is Localized.";
string $matchPattern =("p_"+$name+".");
string $matches[] =`displayString -q -k $matchPattern`;
if(!`size $matches`) error -n"No registered string resources.";
// header
print("// File "+$name+".pres.mel\n");
print("// Resources for Script: "+$name+"\n");
print("// \n");
print("// ----------------------------\n");
print("// Registered string resources:\n");
print("// ----------------------------\n");
for($key in $matches)
{
// Look up the string value
string $resValue =`displayString -q -v $key`;
// Split the id into subparts to get the unique string part
string $idPart = stringRemovePrefix($key,$matchPattern);
// Encode escape characters in the resource value
string $resValueEncoded =`encodeString $resValue`;
// Format and generate the correct initialization string
printResourceString($name, $idPart, $resValueEncoded);
}
}
これを
tryGeneratePres("sample");
と実行することで、スクリプトエディタの履歴に雛形が出力されるので、英語部分を各言語に訳したら sample.pres.melという名前のファイルに保存して、ja_JPフォルダに保存します。
これで日本語版の Mayaで翻訳されたラベルが表示されます。
また、printではなく displayString -deleteで出力すれば重複解除のスクリプトも作れるような気もします。
ただ、これを使って多言語化してしまうと、毎回 tryLoadLanguageResources.melを一緒に配布するか、InitStrings.melの中に同じプロシージャを書き込んでおく必要があるけど、昔のままでもメインスクリプトに毎回 .res.melファイルを読み込むプロシージャを描き込んでいるので、別のスクリプトファイルへ分離できるだけマシかなとか、今後どちらを使っていくか悩みどころです。
あと、mayaのヘルプの
Maya 開発者ヘルプ > テクニカル ノート > プラグインを国際化する
にも関連した解説が書かれているので読んでみるのも良いでしょう。

0 件のコメント:
コメントを投稿