Yes Second Life

セカンドライフに早9年、現役セカンドライファーの考えてること

子プリムに名前でアクセスする

2014年、セカンドライフ技術系アドベントカレンダーの1発めの記事です。

セカンドライフのオブジェクトは、いくつかのプリムをリンクさせて作成するわけですが、リンクされた子プリムには基本的に数値インデックスでしかアクセスできません。

llMessageLinked(2, 0, llGetScriptName(), "");    // 第1引数の「2」がインデックス

llSetLinkPrimitiveParams(3, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);    // 第1引数の「3」がインデックス

しかし、子プリムの番号はリンクをやり直したりすると変わってしまいます。これではそのたびに、スクリプトの数値インデックスの変更が必要で不便。できれば子プリムの名前を指定してアクセスしたいところです。そこで、最初に名前とインデックスの索引をつくってしまう方法が楽です。

list linkPrims;    // 索引格納用リスト


// 索引を作成
createIndex()
{
    integer i;
    linkPrims = ["root"];    // インデックス0はルートプリムを表す
    for(i=1; i<=llGetNumberOfPrims(); i++)
    {
        // インデックス順に子プリムの名前をlinkPrimsへ格納
        string linkPrim = llGetLinkName(i);
        linkPrims += [linkPrim];
    }
}

// 名前をインデックスに変換
integer getIndex(string name)
{
    return llListFindList(linkPrims, [name]);   
}


default
{
    state_entry()
    {
        createIndex();
    }

    touch_start(integer num)
    {
    // 子プリムに名前でアクセス
        llSetLinkColor(getIndex("ResetButton"), <1.0, 0.0, 0.0>, ALL_SIDES);
    }

    // リンク変更時にリセット(いちごさんの指摘で追加)
    changed(integer change)
    { 
        if(change & CHANGED_LINK)
        {
            llResetScript(); 
        }
    }
}

この方法だと、機能追加でHUDにボタンを追加したりしても、子プリムの名前を変えないかぎりスクリプトのインデックスは変更不要でメンテも楽ですね( ̄∇  ̄ )