2010年5月27日木曜日

サイズ変更スクリプト

今回はサーバー1.38から追加された関数を使った簡単なサイズチェンジスクリプトです。。。まあいわゆるリサイズスクリプトと同じようなスクリプトですねw

古いタイプのリサイズスクリプトは子プリムにも全てスクリプトが入ってて、親プリムからllMessageLinkedで子プリムのスクリプトに信号を送ってリサイズするようになってると思いますが、1.38の新関数を使えば子プリムのスクリプト無しで動作するものが作れるので、スクリプトの負荷を特に心配しなくてもよくなります^^

このスクリプトはllGetLinkPrimitiveParamsで最初に全プリムの位置とサイズを取得してリストに記録しておいて、ダイアログで選んだサイズに合わせて全プリムの倍率(位置、サイズ)をllSetLinkPrimitiveParamsFastで変えるようにしました。
// サイズチェンジ
integer listen_handle;
integer CHANNEL;
list prims;  // 位置、サイズ記録用リスト
list menu=["Size S","Size M","Size L","Cancel"];  // メニュー用

set_size(float f)
{  // プリムの位置とサイズを変える
    llSetLinkPrimitiveParamsFast(LINK_ROOT,[PRIM_SIZE,llList2Vector(prims,3)*f]);  // 親プリム
    integer i;
    integer j=llGetListLength(prims);
    for (i=4; i < j; i+=2) {  // 子プリム
        llSetLinkPrimitiveParamsFast(i/2,[PRIM_POSITION,llList2Vector(prims,i)*f,PRIM_SIZE,llList2Vector(prims,i+1)*f]);
    }
}

default
{
    state_entry()
    {
        integer i;
        integer j=llGetNumberOfPrims();  // リンクしてるプリムの数
        vector v=llGetRootPosition();  // 親プリムの位置
        rotation r=llGetRootRotation();  // 親プリムのローテーション
        list l;
        for (i=0; i <= j; i++) {
            l=llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_SIZE]);  // プリムの位置、サイズを取得して
            prims+=[(llList2Vector(l,0)-v)/r,llList2Vector(l,1)];  // ローカル位置とサイズをリストに記録
        }
        llOwnerSay("Size saved.");
    }

    touch_start(integer total_number)
    {
        key id=llDetectedKey(0);  // タッチしたアバターのキー
        if (id == llGetOwner()) {  // オーナーだったら
            llListenRemove(listen_handle);
            CHANNEL=llCeil(llFrand(2147483646));  // ランダムにチャンネルを決める
            listen_handle=llListen(CHANNEL,"",id,"");  // リッスン
            llSetTimerEvent(600);  // タイムアウト600秒
            llDialog(id,"Size change",menu,CHANNEL);  // ダイアログ
        }
    }

    timer()
    {
        llSetTimerEvent(0);
        llListenRemove(listen_handle);  // リッスン中止
    }

    listen(integer channel, string name, key id, string msg)
    {
        llSetTimerEvent(0);
        llListenRemove(listen_handle);
        if (channel == CHANNEL && id == llGetOwner())
        {  // ダイアログの選んだボタンに応じてサイズ変更
            if (msg == "Size S") set_size(0.8);
            else if (msg == "Size M") set_size(1.0);
            else if (msg == "Size L") set_size(1.2);
        }
    }
}

常に最初に記録した値を基準にしてサイズを変えるようにしてるので、プリムやスクリプトを修正するときは、サイズが狂ってこないように倍率1.0(サイズM)に戻してから行ってくださいね。

2プリム以上あるオブジェクトで使ってください。1プリムのものは親プリムのリンク番号が0になるのでこのままでは動きません^^;

0 件のコメント:

コメントを投稿