« カスタムパラメータの順番を入れ替えられないので激怒してプロキシ。 | トップページ | 同じ名前の子をイッキに選択するの。 »

2011年12月 9日 (金)

万死のカスタムパラメータにフロントエンド UI スクリプトで天誅。

昨日のつづき。





標準のカスタムパラメータセットでは、パラメータの表示順を変えることもできないし、グループ表示とかスライダ幅調整だとか、そういう高度な UI もできないし、ならばスクリプトでやろう、という話をします。



昨日と同じシナリオで行きましょう。 シーンルートに Hage という名前のカスタムパラメータセットがあるんですが、これがまた汚くて見づらいファッキンプロパティでして万死に値します。 どげんかせんといかん。 はい、同じシナリオです。


どげんかしましょう。 この万死プロパティを便利に使うための PPG を、スクリプトで生成します。




JScript
---------------------------------------------------------------

//    シーンに残らないカスタムプロパティを作成  oP に格納
var oP = XSIFactory.CreateObject( "CustomProperty" );
oP.name = "Hage Proxy";


//    元になるカスタムプロパティセットのパラメータを全部取得
var oCPSet = ActiveSceneRoot.Properties( "Hage" );
var oParamA = oCPSet.Parameters( "AAAAAAAAAAAAAA" );
var oParamB = oCPSet.Parameters( "bbbb" );
var oParamC = oCPSet.Parameters( "CCC" );



//    プロキシパラメータを作成
oP.AddProxyParameter( oParamA, "aaa", "Hage A" );
oP.AddProxyParameter( oParamB, "bbb", "Hage B" );
oP.AddProxyParameter( oParamC, "ccc", "We pray for Fukushima" );



//    以下、どのようにでも UI 作成
//        UI を作るときのアイテムの名前は、上のプロキシパラメータで指定した第2引数
//        つまりこの場合、aaa, bbb, ccc
//        (例)    Hage の CCC というパラメータに対するプロキシパラメータは、
//            この PPG の中では ccc という名前で呼ばれ、UI上には "We pray for Fukushima" と表示される


var oL, oItem;
oL = oP.PPGLayout;

oL.AddGroup( "HegeHege" );
    oL.AddRow();
        oItem = oL.AddItem( "aaa" );
        oItem.SetAttribute( siUICX, 45 );
        oItem.SetAttribute( siUIWidthPercentage,40 );
        oItem.SetAttribute( siUINoSlider, true );
        oItem = oL.AddItem( "bbb" );
    oL.EndRow();
oL.EndGroup();

oL.AddGroup();
    oL.AddGroup();
        oL.AddGroup();
            oL.AddGroup();
                oItem = oL.AddItem( "ccc" );
                oItem.SetAttribute( siUICX, 85 );
            oL.EndGroup();
        oL.EndGroup();
    oL.EndGroup();
oL.EndGroup();

oL.AddRow();
    oItem = oL.AddButton( "Remove", "Remove Animation ⊂(^ω^ )" );
    oItem = oL.AddButton( "Reset", "( ^ω^)⊃ Reset Value" );
oL.EndRow();



//    Logic 使えば、元のカスタムプロパティセットではできないこんなことも
oL.Language = "JScript";
oL.Logic =    Remove_OnClicked.toString()+
            Reset_OnClicked.toString();


//    アニメーション全て削除
function Remove_OnClicked()
{
    var oParams = PPG.Inspected(0).Parameters;
    RemoveAllAnimation( oParams );
}


//    全部のパラメータにゼロを入れる

function Reset_OnClicked()
{

    //    ちなみに 0 番目のパラメータは PPG.name なので、除外して、1からスタート
    var oParams = PPG.Inspected(0).Parameters;
    for ( var i=1; i<oParams.count; i++ )
    {
        oParams(i).value = 0;
    }
}


//    Inspect しておしまい
InspectObj( oP );




---------------------------------------------------------------



このスクリプトを実行すると、

Hageproxy

このようになります。


シーンルートには、元になる Hage があります。 その PPG が画像右側です。 万死です。

そして画像左側の Hage Proxy という PPG は、Hage を元にして作った、便利 PPG です。  昨日書いた記事と同様、Hage のパラメータをプロキシパラメータとして埋め込んでいます。 そして PPGLayout を駆使して並び方の調整、表示する名前の変更、グループ表示、ボタン追加などをやっています。 この辺が、スクリプトじゃないとできない所だと思います。



そしてこの Hage Proxy ですが、シーンルートなどに実体がありません。 閉じたらハイそれまでよ、という PPG です。 スクリプトが実行されるたびにその都度生成され、閉じたら死ぬ PPG です。

昨日のやり方だと、Hage とは別に、シーンにカスタムプロパティセットを作る必要がありました。 ブツの数を増やしたくない、シンプルに保ちたい場合は、今回のように、実体の残らない PPG にするのがよろしかろうと思います。

実体を残さないもうひとつの利点は、表示の順番や表示する項目などを、いつでも何度でも書き換えられることです。  昨日のやり方だと、一度プロキシパラメータを作ってしまうと、パラメータの表示名くらいは変えられますが、順番などは変えられず、またゼロから作り直すしかありませんでした。  今回の場合は、そもそもスクリプトを実行するたびに PPG を作り直すんですから、どのみち毎回作り直しです。でもその作り直し作業は、手でドラッグ&ドロップをするのではなく、スクリプトをサッと書き換えるだけです。コピペで順番を換えたり。断然ラクです。




もうひとつのポイントは、このスクリプトは自己インストール型である必要は無いということです。 ただのスクリプトとして、スクリプトエディタから実行してもいいし、ボタンを作ってもいいし、独自のスクリプトランチャから発射してもいいし、なんでもいいです。

通常、パラメータやボタンの配置などを司る PPGLayout は、自己インストール型のプロパティ、つまりプラグインとして存在しないと、その UI を保てません。 普通に Animate > Create > Parameter > New Custom Parameter Set から作るカスタムパラメータセットでは、上のような UI は出来ないのです。 出来てもそのセッション内でしか有効でなく、XSI の再起動後には UI が壊れてしまいます。

しかし今回の場合は、そもそもシーンと一緒にセーブするプロパティではありません。その場で生成し、その場で死ぬプロパティです。 ウインドウを開いて閉じるまでその UI が使えればいいわけです。 なので、自己インストール型もクソもなく、ただスクリプトでその場限りの UI を構築すればいいということになります。 実体としては、元のカスタムパラメータセットである Hage がシーンと一緒にセーブされていればそれで良く、Hage の値をいじる時にこのスクリプトが実行されれば良いわけです。 Hage に対するその場限りのフロントエンドを作っていると考えればいいと思います。

自己インストール型にしなくてもいいということは、そのシーンデータを人に渡すときなどに、先方の環境で特別なプラグインなどが必要ないということになります。 これは大きなメリットだと思います。 シーンデータを納品しなければいけない仕事などで、先方に「このプラグインがないとシーンを開けません」 などと言わずに済みます。 これはデカいです。 納品時に、「もし今後そちらでデータをいじるなら、このスクリプトを使うと便利でっせ。無くても問題ないですけど」 と言ってスクリプトを渡してあげたりすると、感謝されるかもしれません。されないかもしれません。知りません。

見づらい UI のままで作業できる人は元の Hage をいじればいいし、便利な UI が欲しい人はスクリプトを実行すればいい。 あれば便利。 なくてもいじれる。 スヴァらしい。


もちろん、このスクリプトを自己インストール型にするのも良いでしょう。 メニューに登録したい時などは、自己インストール型にするしかありませんしね。 そして、このスクリプトを自己インストール型にしたところで、やはり、それを先方にも配布する必要はありません。 何度も言うように実体としては Hage が残っていればそれでよく、このスクリプトはあくまでもフロントエンドですから。 あれば便利。 なくてもいじれる。 スヴァらしい。








最大の問題は、「俺、スクリプト書けねえよ ⊂( ^ω^)⊃ニューン という人には出来ないということです。 


解決策としては、

 1.社内のテクニカル野郎を脅迫して書かせる
 2.junki にビールをおごって書かせる
 3.自分で努力する


の3つしかありません。 2を強くおすすめします。 



3の人のために、以下にポイントを書いておきます。 上のスクリプトを雛形にして、必要部分を書き換えるだけです。 とかエラソーなこと書いて、そんなに大したスクリプトじゃありません。 もっと素敵なやつを誰か書いて下さい。





//    シーンに残らないカスタムプロパティを作成  oP に格納
var oP = XSIFactory.CreateObject( "CustomProperty" );
oP.name = "Hage Proxy";


ここでプロパティを作成します。 シーンルートとか、何かのオブジェクトにぶら下げるのではなく、いわば空中に作成するようなものです。 閉じれば終わりのプロパティ。 2行目は名前なので何でもいいです。2バイト文字も使える。 なんならこの2行目が無くても別にいいです。 なにやら適当な名前が付きますが。






//    元になるカスタムプロパティセットのパラメータを全部取得
var oCPSet = ActiveSceneRoot.Properties( "Hage" );
var oParamA = oCPSet.Parameters( "AAAAAAAAAAAAAA" );
var oParamB = oCPSet.Parameters( "bbbb" );
var oParamC = oCPSet.Parameters( "CCC" );


ここは重要ですね。 元になるカスタムプロパティセット内にあるパラメータを、全部取得します。 パラメータを取得しておかないことには、プロキシパラメータを作れませんから。 まあ、この例のように oParamA などの変数に格納せずとも、いきなり次の AddProxyParameter メソッドに食わせてもいいのですが、説明上わかりやすかろうということで、今回はこのように格納しています。

1行目では、シーンルートに Hage というプロパティがあることが前提の書き方になっています。 本題から逸れて煩雑なスクリプトになるのを避けるために今回はあえてエラーチェックを入れていませんが、ほんとはエラーチェックすべきです。つまり、もしそのプロパティが存在した場合は進め、存在しない場合はエラー出して終了せよ、というチェックです。






//    プロキシパラメータを作成
oP.AddProxyParameter( oParamA, "aaa", "Hage A" );
oP.AddProxyParameter( oParamB, "bbb", "Hage B" );
oP.AddProxyParameter( oParamC, "ccc", "We pray for Fukushima" );


ここも重要というか、核心ですね。 プロパティ内に、プロキシパラメータを作成しています。 

第1引数は、たったさっき取得した oParamA など、元のカスタムパラメータセット内のパラメータです。 

第2引数は、作られるプロキシパラメータの、この Hoge Proxy というプロパティ内における名前です。 aaa となっています。 この行で作られたプロキシパラメータは、スクリプト的には aaa と名づけられたということです。 以降、このスクリプトの中でこのパラメータを参照したいときは aaa と呼ばれます。

第3引数は UI 上に表示する名前です。 "Hage A"  などと、スペースを入れたりすることもできます。





//    以下、どのようにでも UI 作成
//        UI を作るときのアイテムの名前は、上のプロキシパラメータで指定した第2引数
//        つまりこの場合、aaa, bbb, ccc
//        (例)    Hage の CCC というパラメータに対するプロキシパラメータは、
//            この PPG の中では ccc という名前で呼ばれ、UI上には "We pray for Fukushima" と表示される

var oL, oItem;
oL = oP.PPGLayout;
 
oL.AddGroup( "HegeHege" );
    oL.AddRow();
        oItem = oL.AddItem( "aaa" );
        oItem.SetAttribute( siUICX, 45 );
        oItem.SetAttribute( siUIWidthPercentage,40 );
        oItem.SetAttribute( siUINoSlider, true );
        oItem = oL.AddItem( "bbb" );
    oL.EndRow();
oL.EndGroup();
 
oL.AddGroup();
    oL.AddGroup();
        oL.AddGroup();
            oL.AddGroup();
                oItem = oL.AddItem( "ccc" );
                oItem.SetAttribute( siUICX, 85 );
            oL.EndGroup();
        oL.EndGroup();
    oL.EndGroup();
oL.EndGroup();
 
oL.AddRow();
    oItem = oL.AddButton( "Remove", "Remove Animation ⊂(^ω^ )" );
    oItem = oL.AddButton( "Reset", "( ^ω^)⊃ Reset Value" );
oL.EndRow();




ここは、詳しい解説は友愛シリーズでも読んでもらえますかね。 上で作成したプロキシパラメータを、PPG 内で、どんな見栄えで表示するかを司っています。


ひとつ留意すべきなのは、PPG にアイテムを追加する(つまり表示させる)行で、

oItem = oL.AddItem( "aaa" );


となっている部分です。 ここで指定する名前は、aaa ですね。 先ほど aaa という名前のプロキシパラメータを作ったばかりですね。 この名前のパラメータを、AddItem メソッドによって UI 上に追加せよと指令を出していることになります。 oParamA ではダメですし、"Hage A" でもダメです。 追加したいのは、このスクリプト内で作ったプロキシパラメータです。 そのスクリプト的な名前は aaa です。 なのでここでは aaa を追加せよと言ってあげないと、XSI 様が迷います。


そしてこの AddItem される順番で UI 上に表示されるわけです。 AddProxyParameter が実行された順番ではありません。 なので、この PPGLayout 部分でどうにでも好きな順番で書けばいいことになります。 




Logic 以下は、オマケみたいなものなので、すいません本題から逸れるので詳しい解説はしません。 ごっそり削除してもOKです。 ボタンを押したらこういうアクションをしろ、とかそういう部分が書かれていますので。

今回の場合は、まあ、サンプルとして、アニメーションを削除するボタン、全部 0 にするボタンを付けています。 普通のカスタムパラメータセットにはこういうボタンを仕込むことはできないけれど、今回のようなスクリプトで作成されたフロントエンド PPG の中ではこんな自由度もありますよ、ということを伝えたかっただけであります。 よくある、X の値が入力されたら連動して Y の値も変わるという、いわゆる OnChanged のロジックも仕込めます。 パラメータの値によって ReadOnly(グレー表示で値変更不可) にしたり解除したりというロジックも仕込めます。 自由です。







このスクリプトを、GUI からの操作で自動生成できるツールを書いたら便利かもしれないなあ、と妄想。 妄想ですよ。



.

|

« カスタムパラメータの順番を入れ替えられないので激怒してプロキシ。 | トップページ | 同じ名前の子をイッキに選択するの。 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 万死のカスタムパラメータにフロントエンド UI スクリプトで天誅。:

« カスタムパラメータの順番を入れ替えられないので激怒してプロキシ。 | トップページ | 同じ名前の子をイッキに選択するの。 »