セカンドライフ ポーズスタンド LSL Script

スタンドの LSL スクリプトです。

オブジェクトのリンク構成と各名前は以下です。

![posestand.png](https://qiita-image-store.s3.amazonaws.com/0/275884/c83fc2ef-7294-8e3b-b43b-6218047ad139.png)

うえのようにリンクプリムを構成したら、以下のスクリプトとアニメーションファイルを入れます。

ポーズスタンドの出来上がりです。


```LSL:PoseStand.LSL

list anim_list;
string current_anim;
integer index = 0;
float distance = 5.0;

start_anim(integer index)
{
    string anim = llList2String(anim_list, index);
    
    if(anim != current_anim)
    {
        llSetText(anim + " " + (string)(index+1) + "/" + (string)llGetListLength(anim_list), <1,0.5,0.5>,1);
        llStartAnimation(anim);
        if(current_anim != "")
        {
            llStopAnimation(current_anim);
        }
        current_anim = anim;
    }
}

load_anim()
{
    integer num = llGetInventoryNumber(INVENTORY_ANIMATION);
    integer i;
    
    anim_list = [];
    
    for(i = 0 ; i < num ; i++)
    {
        anim_list += llGetInventoryName(INVENTORY_ANIMATION, i);
    }
}


default
{
    state_entry()
    {
        //llSetClickAction(CLICK_ACTION_SIT);
        llSitTarget(<0.0, 0.0, 1>, ZERO_ROTATION);
        load_anim();
    }

    touch_start(integer num)
    {
        string btn_name = llGetLinkName(llDetectedLinkNumber(0));
        if(btn_name == "left")
        {
            index++;
            if(index >= llGetListLength(anim_list))
            {
                index = 0;
            }
            start_anim(index);
        }
        else if(btn_name == "right")
        {
            index--;
            if(index < 0)
            {
                index = llGetListLength(anim_list) -1;
            }
            start_anim(index);
        }
    }

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            key av = llAvatarOnSitTarget();
            if (av)
            {
                llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION | PERMISSION_CONTROL_CAMERA);
            }
            else
            {
                if (current_anim != "")
                {
                    //start_anim(index);
                }
                llReleaseControls();
                llReleaseCamera(av);

                llResetScript();
            }
        }
        else if(change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            llStopAnimation("sit");
            start_anim(index);
        }
        
        if(perm & PERMISSION_CONTROL_CAMERA)
        {
            vector rot = llRot2Euler(llGetLocalRot());
            
            llSetCameraParams(
                [
                    CAMERA_ACTIVE, 1,
                    CAMERA_BEHINDNESS_ANGLE, 0.00,
                    CAMERA_BEHINDNESS_LAG, 0.00,
                    CAMERA_DISTANCE, 0.00,
                    CAMERA_FOCUS, llGetPos() + <0.0, 0.0, 1.0>,
                    CAMERA_FOCUS_LAG, 0.00,
                    CAMERA_FOCUS_LOCKED, TRUE,
                    CAMERA_FOCUS_OFFSET, <0.0, 0.0, 0.0>,
                    CAMERA_FOCUS_THRESHOLD, 0.00,
                    CAMERA_PITCH, 0.0,
                    CAMERA_POSITION, 
                        llGetPos() +
                        <
                            llSin(rot.z)*distance, 
                            -llCos(rot.z)*distance,
                            2.5
                        >,
                    CAMERA_POSITION_LAG, 0.00,
                    CAMERA_POSITION_LOCKED, TRUE,
                    CAMERA_POSITION_THRESHOLD, 0.00
                ]);
        }
    }
}

```