boat script (typeB)

忘れないように個人的な記録です。プログラマーではないので、つこみ所満載でしょうが、やさしく見守ってやってください。アドバイス等は歓迎します。スクリプトがわかる方は改良して使って頂いてもかまいません。

mm powerboat XS のスクリプトです。boat9というのが出てきますが、開発番号でpowerboat XSが9番目のボートだからです。ポーズ(アニメ)は自分で作っていますが、サウンドファイルは他の方のものを使っているので、各自用意してください。このページはビルダー向けに書いています。値をかえればものすごく速い乗り物も出来ますが、フリーズしたり、落ちたりする事が多くなります。そんなときボートが乗り捨てられないで、消えるように考えています。インワールドで他人に迷惑をかけないように、こころがけしましょう。:-)

最初に出てくるboatbound scriptについて、最初にかいておきますが、LSLの説明を読むと、物理状態のオブジェクトにllApplyImpulse()などの関数で直接力を与えるのは良くないとなっております、実際ボートは水面に接してる時と離れたときでは極端に抵抗が違うように感じられます、そのため直進方向の力を加えて上下に揺らすようなことを来ると、水面を離れた瞬間に、宇宙のかなたに消えてしまうようなことがおきます。でも回転する力なら、まあおかしくなってもその場で回るだけだという安易な考えで使用しています。すみません。

rootプリム内は

boatbound script

vector defaultbound = <0, -1, 0>;
float boatmass = 1.0;
float wavetime = 4.0;

boundBoat(vector boundvec)
{
    vector impulse = <boundvec.x,boundvec.y,boundvec.z>* boatmass;
    llApplyRotationalImpulse(impulse, TRUE);
}

jumpdBoat(vector jumpvec)
{
    vector impulsej = <jumpvec.x,jumpvec.y,jumpvec.z>* boatmass;
    llApplyImpulse(impulsej, FALSE);
}

default
{
    state_entry()
    {
        boatmass = llGetMass();
        wavetime = 2.0;
        defaultbound = <0, -0.5, 0>;
        llSetTimerEvent(wavetime);
    }

    timer()
    {
        vector nowvel = llGetVel() / llGetRot();
        float nowspeed = nowvel.x / 4;
        if (nowspeed > 2.5)
        {
                wavetime = 1.8;
                defaultbound = <0, -0.5, 0>;
                llSetTimerEvent(wavetime);
        }
        else if (nowspeed > 1.5)
        {
                wavetime = 1.5;
                defaultbound = <0, -0.6, 0>;
                llSetTimerEvent(wavetime);
        }

        else if (nowspeed > 1.0)
        {
                wavetime = 1.3;
                defaultbound = <0, -0.8, 0>;
                llSetTimerEvent(wavetime);
        }

        else if (nowspeed > 0.5)
        {
                wavetime = 1.5;
                defaultbound = <0, -1.0, 0>;
                llSetTimerEvent(wavetime);
        }
        else
        {
            wavetime = 4.0;
            defaultbound = <0, -0.5, 0>;
            llSetTimerEvent(wavetime);
        }

        boundBoat(defaultbound);
    }
}

DialogTimer script

integer WBREZ = 666;
integer MTIMERON = 667;
integer MTIMEROFF = 668;
integer MTIMEOUT = 669;

default
{
    state_entry()
    {

    }

    on_rez(integer num)
    {
        llResetScript();

    }

    link_message(integer sender_number, integer number, string message, key id)
    {

            if (number != 0)
            {
                if (number == MTIMERON)
                {
                    llSetTimerEvent(60.0);
                }
                if (number == MTIMEROFF)
                {
                    llSetTimerEvent(0.0);
                }
            }

    }

    timer()
    {
        llMessageLinked(LINK_THIS,MTIMEOUT,"","");
        llSetTimerEvent(0.0);
    }
}

mm Boat9 script

string mainname = "mm Powerboat XS";
string animation_name1="mm_boat9_1";
string animation_name2="mm_boat9_1R";
string animation_name3="mm_boat9_1L";

vector sit_pos1 = <3.0, -0.3, 0.6>;//<FF,LL,UP>
vector sit_rot1 = <0.0, -0.0, 0.0>;
vector camera_eye1 = <-5.0, 0.0, 4.0>;
vector camera_at1 = <0.0, 0.0, 2.0>;
vector mlinear = <0, 0, 0>;
vector mangular  = <0, 0, 0>;

float yaw = 2.0;
float maxspeed = 20;
float speed = 0;
float hoverhight = 0.1;
float nowspeed = 0;

integer WBREZ = 666;
integer MTIMERON = 667;
integer MTIMEROFF = 668;
integer MTIMEOUT = 669;
integer dialogchannel;
integer handle;
integer driverMode;//0=owner,1=group,3=anu
integer steeringLinkNum=0;
integer light = FALSE;
integer engine = FALSE;
integer kaji = 0;
integer gearposition = 0;
integer cmin = 1000000000; //chat canel -2147483647 <
integer cmax = 2000000000; // < 2147483647

key agent = NULL_KEY;
key notelinpos = NULL_KEY;
key notelinrot = NULL_KEY;
key notelineye = NULL_KEY;
key notelincat = NULL_KEY;

list sd37menulist = ["Owner","Group","Anyone","Light on","Cancel"];
list sd37menulist1 = ["Owner","Group","Anyone","Light off","Cancel"];
list sd37menulist2 = ["STOP","Light on","Cancel"];
list sd37menulist3 = ["START","Light on","Cancel"];
list sd37menulist4 = ["STOP","Light off","Cancel"];
list sd37menulist5 = ["START","Light off","Cancel"];

makechanelnum()
    {
        dialogchannel = ((integer)llFrand(cmax - cmin) + cmin);
    }

    loadNoteConfig()
    {
        notelinpos = llGetNotecardLine("config", 1);

        notelinrot = llGetNotecardLine("config", 3);

        notelineye = llGetNotecardLine("config", 5);

        notelincat = llGetNotecardLine("config", 7);
    }

initParam() {
    llSetVehicleType(VEHICLE_TYPE_BOAT);

    llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0);
    llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 2.5);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.5);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 1.0);

    llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 3.0);
    llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.5);
    llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_OFFSET, <-5, 0, 0>);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 3.0);
    llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.5);
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.10);
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 3.00);

    llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight);
    llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.9);
    llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 3.00);

    llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 1.0);
    llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 1.0);
    llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 1.0);

    llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,3,0> * DEG_TO_RAD));

    llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <50.0,0.0,1000.0>);
    llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE,<10.0,10.0,10.0>);
    llSetVehicleFlags(VEHICLE_FLAG_NO_DEFLECTION_UP
                    | VEHICLE_FLAG_LIMIT_MOTOR_UP
                    | VEHICLE_FLAG_HOVER_WATER_ONLY);
    gearposition = 0;
}

getLinkNums() {
    integer i;
    integer linkcount=llGetNumberOfPrims();
    for (i=1;i<=linkcount;++i) {         string str=llGetLinkName(i);         if (str=="steering_wheel") steeringLinkNum=i;     } } default {     state_entry()     {         loadNoteConfig();         makechanelnum();         getLinkNums();         llMessageLinked(LINK_SET, 0, "Lightoff", "");         llCollisionSound("", 0.0);         llSetSitText("Sit");         llSitTarget(sit_pos1, llEuler2Rot(sit_rot1 * DEG_TO_RAD));         llSetCameraEyeOffset(camera_eye1);         llSetCameraAtOffset(camera_at1);         initParam();         driverMode = 0;         llPreloadSound("starter");         llPreloadSound("REV Engine");             }          on_rez(integer num)     {         vector pos = llGetPos();         float water_height = llWater(llGetVel());         float ground_height = llGround(llGetVel());         if (water_height > ground_height)
        {
            pos.z = water_height + 0.3;
            llSetPos(pos);
        }

        llResetScript();

    }

    touch_start(integer total_number)
    {
        agent = llAvatarOnSitTarget();
            if (agent == NULL_KEY)
            {
                if (llDetectedKey(0) == llGetOwner())
                {
                    if (light == FALSE)
                    {
                        llDialog(llGetOwner(),"Set Driver mode or color select.",sd37menulist,dialogchannel);
                        light = TRUE;
                    }
                    else
                    {
                        llDialog(llGetOwner(),"Set Driver mode or color select.",sd37menulist1,dialogchannel);
                        light = FALSE;
                    }
                handle = llListen(dialogchannel,"","","");
                llMessageLinked(LINK_THIS,MTIMERON,(string)nowspeed,"");
                }
                else
                {
                }
            }
            else
            {
                if (engine == TRUE && light == FALSE)
                {
                    llDialog(agent,"Engine & Light swich.",sd37menulist2,dialogchannel);
                    handle = llListen(dialogchannel,"","","");
                    llMessageLinked(LINK_THIS,MTIMERON,(string)nowspeed,"");
                }
                else if (engine == FALSE && light == FALSE)
                {
                    llDialog(agent,"Engine & Light swich.",sd37menulist3,dialogchannel);
                    handle = llListen(dialogchannel,"","","");
                    llMessageLinked(LINK_THIS,MTIMERON,(string)nowspeed,"");
                }
                 else if (engine == TRUE && light == TRUE)
                {
                    llDialog(agent,"Engine & Light swich.",sd37menulist4,dialogchannel);
                    handle = llListen(dialogchannel,"","","");
                    llMessageLinked(LINK_THIS,MTIMERON,(string)nowspeed,"");
                }
                 else if (engine == FALSE && light == TRUE)
                {
                    llDialog(agent,"Engine & Light swich.",sd37menulist5,dialogchannel);
                    handle = llListen(dialogchannel,"","","");
                    llMessageLinked(LINK_THIS,MTIMERON,(string)nowspeed,"");
                }
            }
    }

    listen(integer channel, string name, key id, string message)
    {
        if (agent == NULL_KEY && id == llGetOwner() )
        {
            if (llListFindList(sd37menulist,[message]) == 0)
            {
                driverMode = 0;
                llSay(0,"set owner only.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }

            else if (llListFindList(sd37menulist,[message]) == 1)
            {
                driverMode = 1;
                llSay(0,"set group driver.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }

            else if (llListFindList(sd37menulist,[message]) == 2)
            {
                driverMode = 3;
                llSay(0,"set anyone drive.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist,[message]) == 3)
            {

                    llMessageLinked(LINK_SET, 0, "Lighton", "");
                    light = TRUE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist,[message]) == 4)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            //-----------------menu1
            if (llListFindList(sd37menulist1,[message]) == 0)
            {
                driverMode = 0;
                llSay(0,"set owner only.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }

            else if (llListFindList(sd37menulist1,[message]) == 1)
            {
                driverMode = 1;
                llSay(0,"set group driver.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }

            else if (llListFindList(sd37menulist1,[message]) == 2)
            {
                driverMode = 3;
                llSay(0,"set anyone drive.");
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist1,[message]) == 3)
            {

                    llMessageLinked(LINK_SET, 0, "Lightoff", "");
                    light = FALSE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist1,[message]) == 4)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
        }
        else if (agent != NULL_KEY && id == agent )
        {
            //---------------menu2
            if (llListFindList(sd37menulist2,[message]) == 0)
            {
                if (agent == llGetOwner() && driverMode == 0)
                    {
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, FALSE]);
                    }
                llSetStatus(STATUS_PHYSICS, FALSE);
                llStopSound();
                llSetTimerEvent(0.0);
                engine = FALSE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist2,[message]) == 1)
            {
                    llMessageLinked(LINK_SET, 0, "Lighton", "");
                    light = TRUE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist2,[message]) == 2)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            //-------------menu3
            if (llListFindList(sd37menulist3,[message]) == 0)
            {
                if (agent == llGetOwner() && driverMode == 0)
                    {
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
                    }
                llSetStatus(STATUS_PHYSICS, TRUE);
                llTriggerSound("starter", 1);
                llSleep(8);
                llLoopSound("Idle 1", 1.0);
                llSetTimerEvent(0.5);
                engine = TRUE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist3,[message]) == 1)
            {

                    llMessageLinked(LINK_SET, 0, "Lighton", "");
                    light = TRUE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist3,[message]) == 2)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            //---------------menu4
            if (llListFindList(sd37menulist4,[message]) == 0)
            {
                if (agent == llGetOwner() && driverMode == 0)
                    {
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, FALSE]);
                    }
                llSetStatus(STATUS_PHYSICS, FALSE);
                llStopSound();
                llSetTimerEvent(0.0);
                engine = FALSE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist4,[message]) == 1)
            {
                llMessageLinked(LINK_SET, 0, "Lightoff", "");
                light = FALSE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist4,[message]) == 2)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            //-------------menu5
            if (llListFindList(sd37menulist5,[message]) == 0)
            {
                if (agent == llGetOwner() && driverMode == 0)
                    {
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
                    }
                llSetStatus(STATUS_PHYSICS, TRUE);
                llTriggerSound("starter", 1);
                llSleep(8);
                llLoopSound("Idle 1", 1.0);
                llSetTimerEvent(0.5);
                engine = TRUE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist5,[message]) == 1)
            {
               llMessageLinked(LINK_SET, 0, "Lightoff", "");
                light = FALSE;
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
            else if (llListFindList(sd37menulist5,[message]) == 2)
            {
                llListenRemove(handle);
                llMessageLinked(LINK_THIS,MTIMEROFF,(string)nowspeed,"");
            }
        }
    }

    link_message(integer sender_number, integer number, string message, key id)
    {

            if (number == MTIMEOUT)
            {
                llWhisper(0,"Dialog Menu is time out.");
                llListenRemove(handle);
            }

    }

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            llListenRemove(handle);
            agent = llAvatarOnSitTarget();
            if (agent != NULL_KEY)
            {
                if (driverMode == 0)//owner only mode
                {
                    if (agent == llGetOwner())
                    {
                        llSetStatus(STATUS_PHYSICS, TRUE);
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
                        llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION |
                                                    PERMISSION_TAKE_CONTROLS |
                                                    PERMISSION_CONTROL_CAMERA);
                        llMessageLinked(LINK_SET, 0, "seated", "");
                        llTriggerSound("starter", 1);
                        llSleep(8);
                    }
                    else
                    {
                        llSay(0,"You are not my owner!");
                        llUnSit(agent);
                        llMessageLinked(LINK_SET, 0, "unseated", "");
                    }
                }

                else if (driverMode == 1)//group mode
                {

                    if (llSameGroup(agent))
                    {
                        llSetStatus(STATUS_PHYSICS, TRUE);
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
                        llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION |
                                                    PERMISSION_TAKE_CONTROLS |
                                                    PERMISSION_CONTROL_CAMERA);
                        llMessageLinked(LINK_SET, 0, "seated", "");
                        llTriggerSound("starter", 1);
                        llSleep(8);
                    }
                    else
                    {
                        llSay(0,"You are not same group!");
                        llUnSit(agent);
                        llMessageLinked(LINK_SET, 0, "unseated", "");
                    }
                }

                else if (driverMode == 3)//anyone driver mode
                {

                        llSetStatus(STATUS_PHYSICS, TRUE);
                        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
                        llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION |
                                                    PERMISSION_TAKE_CONTROLS |
                                                    PERMISSION_CONTROL_CAMERA);
                        llMessageLinked(LINK_SET, 0, "seated", "");
                        llTriggerSound("starter", 1);
                        llSleep(8);
                }
            }

            else
            {
                 key perm_key = llGetPermissionsKey();
                if (perm_key != NULL_KEY)
                {
                    llClearCameraParams();
                    llReleaseControls();
                    llStopAnimation(animation_name1);
                }
                llSetStatus(STATUS_PHYSICS, FALSE);
                llMessageLinked(LINK_SET, 0, "unseated", "");
                llStopSound();
                engine = FALSE;
                agent = llAvatarOnSitTarget();
                llMessageLinked(LINK_ALL_OTHERS,0,"0","");
                llSetTimerEvent(0.0);
            }

        }

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

    dataserver(key queryid , string data)
    {
        if (queryid == notelinpos)
        {
            sit_pos1 = (vector)data;
        }

        else if (queryid == notelinrot)
        {
            sit_rot1 = (vector)data;
        }

        else if (queryid == notelineye)
        {
            camera_eye1 = (vector)data;
        }

        else if (queryid == notelincat)
        {
            camera_at1= (vector)data;
        }

        llSitTarget(sit_pos1, llEuler2Rot(sit_rot1 * DEG_TO_RAD));
        llSetCameraEyeOffset(camera_eye1);
        llSetCameraAtOffset(camera_at1);

    }

    run_time_permissions(integer perm)
        {
                if (perm & PERMISSION_CONTROL_CAMERA) {
            llSetCameraParams([
                      CAMERA_ACTIVE, 1,
                      CAMERA_BEHINDNESS_ANGLE, 30.0,        //10.0
                      CAMERA_BEHINDNESS_LAG, 0.4,       //0.4
                      CAMERA_DISTANCE, 10.0,             //3.0
                      CAMERA_FOCUS_LAG, 0.1 ,
                      CAMERA_FOCUS_LOCKED, FALSE,
                      CAMERA_FOCUS_THRESHOLD, 1.0,
                      CAMERA_PITCH, 15.0,           //0.0
                      CAMERA_POSITION_LAG, 0.1,     //0.1
                      CAMERA_POSITION_LOCKED, FALSE,
                      CAMERA_POSITION_THRESHOLD, 1.0,   //1.0 (1-4)
                      CAMERA_FOCUS_OFFSET, ZERO_VECTOR
                    ]);

            }
        if (perm != 0)
        {
            llStartAnimation(animation_name1);
            llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN , TRUE, FALSE);
            llLoopSound("Idle 1", 1.0);
            engine = TRUE;
            llSetTimerEvent(0.5);
        }
    }

    timer()
    {
        llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, mlinear);

        vector nowvel = llGetVel() / llGetRot();
        nowspeed = nowvel.x / 4;
        llMessageLinked(LINK_ALL_OTHERS,kaji,(string)nowspeed,"");

        if (nowspeed >= 4)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,10,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.5);
            llLoopSound("drive loop 4", 1.0);
        }
        else if (nowspeed >= 3 && nowspeed < 4)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,8,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.4);
            llLoopSound("drive loop 3", 1.0);
        }
        else if (nowspeed >= 2 && nowspeed < 3)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,6,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.3);
            llLoopSound("fast loop 1", 1.0);
        }
        else if (nowspeed >= 1 && nowspeed < 2)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,4,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.2);
            llLoopSound("fast loop 1", 1.0);
        }
        else if (nowspeed >= 0.8 && nowspeed < 1)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,3,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.15);
            llLoopSound("slow loop 1", 1.0);
        }
        else if (nowspeed >= 0.6 && nowspeed < 0.8)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,2,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.1);
            llLoopSound("slow loop 1", 1.0);
        }
        else if (nowspeed >= 0.4 && nowspeed < 0.6)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,1,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight + 0.05);
            llLoopSound("slow loop 1", 1.0);
        }
        else if (nowspeed > 0.01 && nowspeed < 0.4)
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,0.0,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight);
            llLoopSound("Idle 1", 0.5);
        }

        else
        {
            llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME,llEuler2Rot(<0,0,0> * DEG_TO_RAD));
            llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, hoverhight);
            llLoopSound("Idle 1", 0.5);
        }
    }

    control(key id, integer held, integer change)
    {
        if(change & CONTROL_FWD &&  held & CONTROL_FWD)
        {
            if (engine == TRUE && gearposition == 0)
            {
                llTriggerSound("REV Engine", 0.5);
            }
        }
        if(change & CONTROL_BACK &&  held & CONTROL_BACK)
        {
                if (engine == TRUE)
            {
                llTriggerSound("boat_horn", 1.0);
            }
        }

        if(change & CONTROL_UP && held & CONTROL_UP)
        {
            if (gearposition <= -1)             {                 gearposition = 0;                 mlinear.x = maxspeed * gearposition / 10 ;                 llWhisper(0, "STAN BY");                              }             else if (gearposition == 0)             {                 gearposition = 2;                 mlinear.x = maxspeed * gearposition / 10 ;                 llWhisper(0, "DEAD SLOW");             }             else if (gearposition == 2)             {                 gearposition = 3;                 mlinear.x = maxspeed * gearposition / 10 ;                 llWhisper(0, "SLOW");             }             else if (gearposition == 3)             {                 gearposition = 5;                 mlinear.x = maxspeed * gearposition / 10 ;                 llWhisper(0, "HALF");             }             else if (gearposition == 5)             {                 gearposition = 10;                 mlinear.x = maxspeed * gearposition / 10 ;                 llWhisper(0, "FULL");             }             else             {                              }         }         if(change & CONTROL_DOWN && held & CONTROL_DOWN)         {             if (gearposition >= 10)
            {
                gearposition = 5;
                mlinear.x = maxspeed * gearposition / 10 ;
                llWhisper(0, "HALF");
            }
            else if (gearposition == 5)
            {
                gearposition = 3;
                mlinear.x = maxspeed * gearposition / 10 ;
                llWhisper(0, "SLOW");
            }
            else if (gearposition == 3)
            {
                gearposition = 2;
                mlinear.x = maxspeed * gearposition / 10 ;
                llWhisper(0, "DEAD SLOW");
            }
            else if (gearposition == 2)
            {
                gearposition = 0;
                mlinear.x = maxspeed * gearposition / 10 ;
                llWhisper(0, "STAN BY");

            }
            else if (gearposition == 0)
            {
                gearposition = -1;
                mlinear.x = maxspeed * gearposition / 10 ;
                llWhisper(0, "ASTERN DEAD SLOW");

            }

        }

        if(change & (CONTROL_RIGHT|CONTROL_ROT_RIGHT) && (held & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)))
        {
            llMessageLinked(steeringLinkNum,3,"","");
            llStopAnimation(animation_name1);
            llStartAnimation(animation_name2);
        }

        if(held & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
        {
            mangular.x += yaw;
            mangular.y -= yaw * 0.5;
            mangular.z -= yaw * 1.2;
            mlinear.y = gearposition / 3 ;
             kaji = 1;
        }

        if(change & (CONTROL_RIGHT|CONTROL_ROT_RIGHT) && !(held & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)))
        {
            mangular.x = 0;
            mangular.y = 0;
            mangular.z = 0;
            mlinear.y = 0;
            kaji = 0;
            llMessageLinked(steeringLinkNum,4,"","");
            llStopAnimation(animation_name2);
            llStartAnimation(animation_name1);
        }

        if(change & (CONTROL_LEFT|CONTROL_ROT_LEFT) && (held & (CONTROL_LEFT|CONTROL_ROT_LEFT)))
        {
            llMessageLinked(steeringLinkNum,4,"","");
            llStopAnimation(animation_name1);
            llStartAnimation(animation_name3);
        }

        if(held & (CONTROL_LEFT|CONTROL_ROT_LEFT))
        {
            mangular.x -= yaw;
            mangular.y -= yaw * 0.5;
            mangular.z += yaw * 1.2;
            mlinear.y = gearposition / 3 ;
            kaji = 2;
        }

        if(change & (CONTROL_LEFT|CONTROL_ROT_LEFT) && !(held & (CONTROL_LEFT|CONTROL_ROT_LEFT)))
        {
            mangular.x = 0;
            mangular.y = 0;
            mangular.z = 0;
            mlinear.y = 0 ;
            kaji = 0;
            llMessageLinked(steeringLinkNum,3,"","");
            llStopAnimation(animation_name3);
            llStartAnimation(animation_name1);
        }

        else
        {
        }

        llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, mangular);
    }
}

config (text file)

sit_pos <Front, Left, up>
<3.0, -0.3, 0.6>
sit_rot
<0.0, 0.0, 0.0>
camera_eye
<-5.0, 0.0,4.0>
camera_at
<0.0,0.0,2.0>

そのほかは

サウンドファイルが8個

  • boat_horn (汽笛)
  • starter  (エンジン始動)
  • REV Engine  (エンジン空吹かし)
  • reverse drive   (後退エンジン音)
  • Idle 1  (アイドリング)
  • slow loop 1  (速度に対応したエンジン音)
  • fast loop 1 (速度に対応したエンジン音)
  • drive loop 3 (速度に対応したエンジン音)
  • drive loop 4 (速度に対応したエンジン音)

アニメーションファイルが3個

  • mm_boat9_1 (運転手用アニメ)
  • mm_boat9_1L (左にハンドルを切った運転手ようアニメ)
  • mm_boat9_1R (右にハンドルを切った運転手ようアニメ)

子プリムに入っているスクリプト

powerboat SX は走行中にリフトして、後部のスタビライザー(私が勝手に呼んでいる、正しい名前は?)から後ろの一部しか海面に接していないため、船体の前側よりおこる引き波はスピードが上がるにつれて後部に移る必要があります、パーティクルを発生させるプリムの位置を動かすのが正しいのでしょうが、ここでは前部と後部とスクリューの3箇所のパーティクルの発生速度をずらして対応しています

particle script1 ( front particle object )


integer flags;
integer on;

set_particle()
 {
 llParticleSystem( [
 PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
 PSYS_PART_START_SCALE, <0.1,1.0, 0>,
 PSYS_PART_END_SCALE, <0.5,10.0, 0>,
 PSYS_PART_START_COLOR, <1,1,1>,
 PSYS_PART_END_COLOR, <1,1,1>,
 PSYS_PART_START_ALPHA, 1.0,
 PSYS_PART_END_ALPHA, 0.0,
 PSYS_SRC_BURST_PART_COUNT, 50,
 PSYS_SRC_BURST_RATE, 0.02,
 PSYS_PART_MAX_AGE, 3.0,
 PSYS_SRC_MAX_AGE, 0.0,
 PSYS_SRC_PATTERN, 4,
 PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
 PSYS_SRC_BURST_SPEED_MIN, 1.0,
 PSYS_SRC_BURST_SPEED_MAX, 3.0,
 PSYS_SRC_ANGLE_BEGIN, 0*DEG_TO_RAD,
 PSYS_SRC_ANGLE_END, 0*DEG_TO_RAD,
 PSYS_SRC_OMEGA, <0,0,0>,
 PSYS_PART_FLAGS, ( 0
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
 ) ] );
 }

default
{
 state_entry()
 {
 on = FALSE;
 llParticleSystem([]);
 }

 link_message(integer sender_num,integer num,string message,key id)
 {
 if ((float)message >= 0.6 && (float)message < 1.0)
 {
 on = TRUE;
 set_particle();
 }
 else
 {
 on = FALSE;
 llParticleSystem([]);

}
 }
}

particle script2 ( Rear particle object (StabilizerL,R))


integer flags;
integer on;

set_particle()
 {
 llParticleSystem( [
 PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
 PSYS_PART_START_SCALE, <1.0,1.0, 0>,
 PSYS_PART_END_SCALE, <0.5,10.0, 0>,
 PSYS_PART_START_COLOR, <1,1,1>,
 PSYS_PART_END_COLOR, <1,1,1>,
 PSYS_PART_START_ALPHA, 1.0,
 PSYS_PART_END_ALPHA, 0.0,
 PSYS_SRC_BURST_PART_COUNT, 50,
 PSYS_SRC_BURST_RATE, 0.02,
 PSYS_PART_MAX_AGE, 5.0,
 PSYS_SRC_MAX_AGE, 0.0,
 PSYS_SRC_PATTERN, 4,
 PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
 PSYS_SRC_BURST_SPEED_MIN, 1.0,
 PSYS_SRC_BURST_SPEED_MAX, 3.0,
 PSYS_SRC_ANGLE_BEGIN, 0*DEG_TO_RAD,
 PSYS_SRC_ANGLE_END, 0*DEG_TO_RAD,
 PSYS_SRC_OMEGA, <0,0,0>,
 PSYS_PART_FLAGS, ( 0
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
 ) ] );
 }

default
{
 state_entry()
 {
 on = FALSE;
 llParticleSystem([]);
 }

 link_message(integer sender_num,integer num,string message,key id)
 {
 if ((float)message >= 1)
 {
 on = TRUE;
 set_particle();
 }
 else
 {
 on = FALSE;
 llParticleSystem([]);

}
 }
}

particle script3 ( particle object (Screw))


integer flags;
integer on;

set_particle()
 {
 llParticleSystem( [
 PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
 PSYS_PART_START_SCALE, <0.3,1.0, 0>,
 PSYS_PART_END_SCALE, <5.5,10.0, 0>,
 PSYS_PART_START_COLOR, <1,1,1>,
 PSYS_PART_END_COLOR, <1,1,1>,
 PSYS_PART_START_ALPHA, 1.0,
 PSYS_PART_END_ALPHA, 0.0,
 PSYS_SRC_BURST_PART_COUNT, 50,
 PSYS_SRC_BURST_RATE, 0.02,
 PSYS_PART_MAX_AGE, 4.0,
 PSYS_SRC_MAX_AGE, 0.0,
 PSYS_SRC_PATTERN, 4,
 PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
 PSYS_SRC_BURST_SPEED_MIN, 4.0,
 PSYS_SRC_BURST_SPEED_MAX, 5.0,
 PSYS_SRC_ANGLE_BEGIN, 0*DEG_TO_RAD,
 PSYS_SRC_ANGLE_END, 0*DEG_TO_RAD,
 PSYS_SRC_OMEGA, <0,0,0>,
 PSYS_PART_FLAGS, ( 0
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
 ) ] );
 }

default
{
 state_entry()
 {
 on = FALSE;
 llParticleSystem([]);
 }

 link_message(integer sender_num,integer num,string message,key id)
 {
 if ((float)message > 0.2)
 {
 on = TRUE;
 set_particle();
 }
 else
 {
 on = FALSE;
 llParticleSystem([]);

}
 }
}

どこでもいいのですが、私は前の方のひとつに、波の音を出すスクリプトを入れています。

サウンドファイルが2種

  • nami  (停泊時の波の音)
  • SubmarineWave  (航行中の波の音)

soundscript


default
{
    state_entry()
    {

    }

    link_message(integer sender_num,integer num,string message,key id)
    {
       if ((float)message >= 0.3 )
       {
          llLoopSound("SubmarineWave", 1.0);
       }

       else
       {
          llLoopSound("nami", 1.0);
       }
    }
}

このpowerboat XS では省略しちゃってますが。
舵を動かすスクリプト。舵を動かすときは、パーティクルスクリプトをスクリューではなく、舵に一緒に入れて舵に伴い向きが変わるようにします。このとき舵をモデリングするときに、回転軸をローカルであわせるのと、Z軸方向にパーティクルが発生するのに注意します。
Rudder script ( rudder object )

rotation defaultrot;
rotation kajirot;
rotation tempkajirot;

default
{
    state_entry()
    {
        defaultrot = llGetLocalRot();
        tempkajirot = llEuler2Rot(<0,0,30> * DEG_TO_RAD);
    }

    link_message(integer sender_num,integer num,string message,key id)
    {
        if (num == 1)
            {
                kajirot = defaultrot * tempkajirot;
                llSetLocalRot(kajirot);
             }
        else if (num == 2)
            {
                kajirot = defaultrot / tempkajirot;
                llSetLocalRot(kajirot);
            }
            else
            {
                llSetLocalRot(defaultrot);
            }
    }
}

RotateSteeringWheel script (Don’t changing the name of the prim “steering_wheel”)

*間違え修正 LINK_THISとなるパラメーターを直接2としていたため、動かなかったところ2014.2.24

rotation rot;
default
{
    state_entry()
    {
        rot = ZERO_ROTATION;
    }
    on_rez(integer num)
    {
        llResetScript();
    }
    link_message(integer sender_num,integer num,string message,key id)
    {
        if (num == 3)
            {
                rotation childRot = llList2Rot(llGetLinkPrimitiveParams(LINK_THIS,
                [PRIM_ROTATION]),0);
                vector targetEluer= DEG_TO_RAD*<30.0,0.0,0.0>;
                rotation targetRot = llEuler2Rot(targetEluer);
                rot = targetRot*childRot/llGetRootRotation()/llGetRootRotation();
                llSetLinkPrimitiveParams(LINK_THIS,[PRIM_ROTATION,rot]);
             }
        else if (num == 4)
            {
                 rotation childRot = llList2Rot(llGetLinkPrimitiveParams(LINK_THIS,
                [PRIM_ROTATION]),0);
                vector targetEluer= DEG_TO_RAD*<-30.0,0.0,0.0>;
                rotation targetRot = llEuler2Rot(targetEluer);
                rot = targetRot*childRot/llGetRootRotation()/llGetRootRotation();
                llSetLinkPrimitiveParams(LINK_THIS,[PRIM_ROTATION,rot]);
            }
            else
            {

            }
    }
}

ラダーの方のスクリプトはデフォルトの回転軸でまわしているので、右に回す、元に戻す、左に回すという3つのパターンで、ルートプリムと連絡をとっています、SteeringWheeも水平または垂直にリンクすれば、同じスクリプトでも可能ですが、傾けてリンクさせたので、ローカル軸で回転させることになり、元に戻るがつかえなく、右に30度回す、左に30度回してもどす、左に30度回す、右に30度回して戻すという4パターンでやっています。いろいろ継ぎ足しながらきたので、スマートではないですね。


boat script (typeB)への1件のコメント

  1. アバター Michie
    Michie コメント投稿者

    ミスを発見 SteeringWheeのスクリプト

    LINK_THISとなるパラメーターを直接2としていたため、ほかのでは動かなかった