Jump to content
Sign in to follow this  
Rolig Loon

Walking through walls

Recommended Posts

A recent forum thread asked how to make an avatar phantom so you can walk through walls.  You can't do that exactly, but you can fake it.  Here's one way....

 

//Walk Through Walls -- Rolig Loon -- February 2012

stop_anim()     // Cancel all current active avatar animations
{
    integer list_pos = 0;
    list Anims2stop = llGetAnimationList(llAvatarOnSitTarget());
    integer list_length = (Anims2stop !=[]);
    if(list_length > 0)
    {
        while(list_pos < list_length)
        {
            llStopAnimation(llList2String(Anims2stop, list_pos));
            list_pos++;
        }
    }
}

string gWalk;
string gStand;
float gAvHeight;

default
{
    state_entry()
    {
        llSetMemoryLimit(8128);
        llSitTarget(<0.0,0.0,0.1>,ZERO_ROTATION);
        gWalk = "CCfWalk02medium";              //Put your own favorite walk anim here
        gStand = "*GA* Pretty Girl Stand V3";   //Put your own favorite stand anim here
    }
    
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            if (llAvatarOnSitTarget())
            {
                llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TAKE_CONTROLS |PERMISSION_TRIGGER_ANIMATION);
            }
            else
            {
                llSetAlpha(1.0,ALL_SIDES);
                llSetTimerEvent(0.0);
            }
        }
    }
    
    run_time_permissions(integer perm)
    {
        if(PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION & perm)
        {
            llSetAlpha (0.0,ALL_SIDES);
            llTakeControls(
                            CONTROL_FWD |
                            CONTROL_BACK |
                            CONTROL_LEFT |
                            CONTROL_RIGHT |
                            CONTROL_ROT_LEFT |
                            CONTROL_ROT_RIGHT |
                            CONTROL_UP |
                            CONTROL_DOWN |
                            0, TRUE, FALSE);
            stop_anim();
            vector size = llGetAgentSize(llAvatarOnSitTarget());
            gAvHeight = size.z;
            llSetTimerEvent(1.0);
        }
    }
    
    timer()  // Adjusts height above whatever is under the av
    {
        list results = llCastRay(llGetPos(), llGetPos() + <0.0,0.0,-2.5>, [RC_REJECT_TYPES, RC_REJECT_AGENTS|RC_REJECT_PHYSICAL, RC_MAX_HITS, 1] );
        vector UnderMe = llList2Vector(results,1);
        llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION, <UnderMe.x, UnderMe.y, UnderMe.z + 0.40*gAvHeight>]);
    }
    
    control(key id, integer level, integer edge)
    {
        if(level & (~edge) & CONTROL_FWD)
        {
            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.05,0.0,0.0>* llGetRot()]);
            llStopAnimation(gStand);
            llStartAnimation(gWalk);
        }
        if (level & (~edge) & CONTROL_BACK)
        {
            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <-0.05,0.0,0.0>*llGetRot()]);
            llStopAnimation(gStand);
            llStartAnimation(gWalk);
        }
        if (level & (CONTROL_ROT_LEFT | CONTROL_LEFT))
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROTATION,llEuler2Rot(<0.0,0.0,1.0>*DEG_TO_RAD)*llGetRootRotation()]);
        }
        if (level & (CONTROL_ROT_RIGHT | CONTROL_RIGHT))
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROTATION,llEuler2Rot(<0.0,0.0,-1.0>*DEG_TO_RAD)*llGetRootRotation()]);
        }
        if (level & CONTROL_UP)
        {
            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.0,0.0,0.05>*llGetRot()]);
        }
        if (level & CONTROL_DOWN)
        {
            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.0,0.0,-0.05>*llGetRot()]);
        }            
        else if (~level & edge)
        {
            llStopAnimation(gWalk);
            llStartAnimation(gStand);
        }
    }
}

 The timer event uses llCastRay to locate whatever surface is directly under you, and then adjusts the height of the object you are sitting on so that your feet are just touching that surface. You may want to fiddle with that height adjustment and with the speed of the timer event to get it just right.  You may also want to add a camera control to set the cam position in a proper spot behind you, in case this doesn't default there naturally.

This is basically a simple non-physical hovercraft script, modified to create the walking illusion. 

  • Like 2

Share this post


Link to post
Share on other sites

I am afraid I know nothing about scripting but an application occurs to me using something like this that you have so generously offered. Would it be possible to somehow adapt it so that two people could at the same time "ride" this object and walk thru the wall together?

Share this post


Link to post
Share on other sites

I love it when someone suggests a way to expand on an idea.  I decided to play with the idea of a two-person "Walk Through Walls" script.  Here's the result. 

It's two scripts, to be placed in a pair of linked pose balls, side by side.  It's probably best to give them distinctive colors so that you know which is which, although each one disappears as soon as someone sits on it.  In my own testing, I was lazy and used the same animations in both scripts (and put them both in each of the pose balls), but you could clearly put different animations in one of them (male/female?).  The only thing you'll want to do is adjust the heights of the balls relative to each other, so that a short person walking next to a tall one doesn't float in the air.  The lead script (in the root prim) controls movement for the pair, and its timer event adjusts their height above whatever is under them. The other script (in the "second" pose ball) follows its orders.

I also added a camera control to both scripts, so that your default camera setting is behind the walking avatars.  I find that I have to hit my ESC key to engage the camera once I sit.

Here's the script for the "lead" pose ball........

//Double Walk Lead -- Rolig Loon -- March 2012stop_anim()     // Cancel all current active avatar animations{    integer list_pos = 0;    list Anims2stop = llGetAnimationList(llAvatarOnSitTarget());    integer list_length = (Anims2stop !=[]);    if(list_length > 0)    {        while(list_pos < list_length)        {            llStopAnimation(llList2String(Anims2stop, list_pos));            list_pos++;        }    }}string gWalk;string gStand;float gAvHeight;default{    state_entry()    {        llSetRot(ZERO_ROTATION);        llSetLinkPrimitiveParamsFast(2,[PRIM_ROT_LOCAL,ZERO_ROTATION]);        llLinkSitTarget(1,<0.0,0.0,0.1>,ZERO_ROTATION);        gWalk = "CCfWalk02medium";              //Put your own favorite walk anim here        gStand = "*GA* Pretty Girl Stand V3";   //Put your own favorite stand anim here        llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);    }        on_rez (integer start)    {        llResetScript();    }        changed(integer change)    {        if (change & CHANGED_LINK)        {            if (llAvatarOnLinkSitTarget(1))            {                llRequestPermissions(llAvatarOnLinkSitTarget(1), PERMISSION_TAKE_CONTROLS |PERMISSION_TRIGGER_ANIMATION|PERMISSION_CONTROL_CAMERA);            }            else if (llAvatarOnLinkSitTarget(1) == NULL_KEY)            {                llSetLinkAlpha(1,1.0,ALL_SIDES);                llSetTimerEvent(0.0);                if (llAvatarOnLinkSitTarget(2) == NULL_KEY)                {                    llResetScript();                }            }        }    }        run_time_permissions(integer perm)    {        if(PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION|PERMISSION_CONTROL_CAMERA & perm)        {            llSetLinkAlpha (1,0.0,ALL_SIDES);            llClearCameraParams(); // reset camera to default            llSetCameraParams([                CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive                CAMERA_BEHINDNESS_ANGLE, 5.0, // (0 to 180) degrees                CAMERA_BEHINDNESS_LAG, 0.0, // (0 to 3) seconds                CAMERA_DISTANCE, 3.0, // ( 0.5 to 10) meters                CAMERA_FOCUS_LAG, 0.05 , // (0 to 3) seconds                CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)                CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) meters                CAMERA_PITCH, 0.0, // (-45 to 80) degrees                CAMERA_POSITION_LAG, 0.0, // (0 to 3) seconds                CAMERA_POSITION_LOCKED, FALSE, // (TRUE or FALSE)                CAMERA_POSITION_THRESHOLD, 0.0, // (0 to 4) meters                CAMERA_FOCUS_OFFSET, <1.0, 0.0, 0.0> // <-10,-10,-10> to <10,10,10> meters            ]);            llTakeControls(                            CONTROL_FWD |                            CONTROL_BACK |                            CONTROL_LEFT |                            CONTROL_RIGHT |                            CONTROL_ROT_LEFT |                            CONTROL_ROT_RIGHT |                            CONTROL_UP |                            CONTROL_DOWN |                            0, TRUE, FALSE);            vector size = llGetAgentSize(llAvatarOnLinkSitTarget(1));            gAvHeight = size.z;            stop_anim();            if((llAvatarOnLinkSitTarget(1) != NULL_KEY)&& (llAvatarOnLinkSitTarget(2) != NULL_KEY))            {                llSetTimerEvent(1.0);            }        }    }        timer()  // Adjusts height above whatever is under the av    {        list results = llCastRay(llGetPos(), llGetPos() + <0.0,0.0,-2.5>, [RC_REJECT_TYPES, RC_REJECT_AGENTS|RC_REJECT_PHYSICAL, RC_MAX_HITS, 1] );        vector UnderMe = llList2Vector(results,1);        llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION, <UnderMe.x, UnderMe.y, UnderMe.z + 0.40*gAvHeight>]);    }        control(key id, integer level, integer edge)    {        if(level & (~edge) & CONTROL_FWD)        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.05,0.0,0.0>* llGetRot()]);            llStopAnimation(gStand);            llStartAnimation(gWalk);            llMessageLinked(2,1,"FWD",NULL_KEY);        }        if (level & (~edge) & CONTROL_BACK)        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <-0.05,0.0,0.0>*llGetRot()]);            llStopAnimation(gStand);            llStartAnimation(gWalk);            llMessageLinked(2,1,"BACK",NULL_KEY);        }        if (level & (CONTROL_ROT_LEFT | CONTROL_LEFT))        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_ROTATION,llEuler2Rot(<0.0,0.0,1.0>*DEG_TO_RAD)*llGetRootRotation()]);        }        if (level & (CONTROL_ROT_RIGHT | CONTROL_RIGHT))        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_ROTATION,llEuler2Rot(<0.0,0.0,-1.0>*DEG_TO_RAD)*llGetRootRotation()]);        }        if (level & CONTROL_UP)        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.0,0.0,0.05>*llGetRot()]);        }        if (level & CONTROL_DOWN)        {            llSetLinkPrimitiveParamsFast(LINK_SET,[PRIM_POSITION,llGetPos() + <0.0,0.0,-0.05>*llGetRot()]);        }                    else if (~level & edge)        {            llMessageLinked(2,2,"STOP",NULL_KEY);            llStopAnimation(gWalk);            llStartAnimation(gStand);        }    }}

 

 And here's the script for the "second" pose ball......

//Double Walk Second -- Rolig Loon -- March 2012stop_anim()     // Cancel all current active avatar animations{    integer list_pos = 0;    list Anims2stop = llGetAnimationList(llAvatarOnSitTarget());    integer list_length = (Anims2stop !=[]);    if(list_length > 0)    {        while(list_pos < list_length)        {            llStopAnimation(llList2String(Anims2stop, list_pos));            list_pos++;        }    }}string gWalk;string gStand;default{    state_entry()    {        gWalk = "CCfWalk02medium";              //Put your own favorite walk anim here        gStand = "*GA* Pretty Girl Stand V3";   //Put your own favorite stand anim here        llLinkSitTarget(2,<0.0,0.0,0.1>,ZERO_ROTATION);  // Be prepared to adjust the sit target as necessary    }        changed(integer change)    {        if (change & CHANGED_LINK)        {            if (llAvatarOnLinkSitTarget(2))            {                llRequestPermissions(llAvatarOnLinkSitTarget(2), PERMISSION_TRIGGER_ANIMATION|PERMISSION_CONTROL_CAMERA);            }            else if (llAvatarOnLinkSitTarget(2) == NULL_KEY)            {                llSetLinkAlpha(2,1.0,ALL_SIDES);            }        }    }        run_time_permissions(integer perm)    {        if(PERMISSION_TRIGGER_ANIMATION|PERMISSION_CONTROL_CAMERA & perm)        {            llSetLinkAlpha (2,0.0,ALL_SIDES);            llClearCameraParams(); // reset camera to default            llSetCameraParams([                CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive                CAMERA_BEHINDNESS_ANGLE, 5.0, // (0 to 180) degrees                CAMERA_BEHINDNESS_LAG, 0.0, // (0 to 3) seconds                CAMERA_DISTANCE, 3.0, // ( 0.5 to 10) meters                CAMERA_FOCUS_LAG, 0.05 , // (0 to 3) seconds                CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)                CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) meters                CAMERA_PITCH, 0.0, // (-45 to 80) degrees                CAMERA_POSITION_LAG, 0.0, // (0 to 3) seconds                CAMERA_POSITION_LOCKED, FALSE, // (TRUE or FALSE)                CAMERA_POSITION_THRESHOLD, 0.0, // (0 to 4) meters                CAMERA_FOCUS_OFFSET, <1.0, 0.0, 0.0> // <-10,-10,-10> to <10,10,10> meters            ]);            stop_anim();        }    }            link_message (integer link, integer num, string msg, key id)    {        if(llAvatarOnLinkSitTarget(2))        {            if(msg == "FWD")            {                llStopAnimation(gStand);                llStartAnimation(gWalk);            }            if (msg == "BACK")            {                llStopAnimation(gStand);                llStartAnimation(gWalk);            }            else if (msg == "STOP")            {                llStopAnimation(gWalk);                llStartAnimation(gStand);            }        }    }}

  EDIT: Added code to force the device to reset the orientation of both poseballs on rez or when both avatars stand up. See my note in a later post.

EDIT2: Added a test in the "second" script to avoid a permission error if nobody is sitting on the second pose ball.

  • Like 2

Share this post


Link to post
Share on other sites

Good luck with it.  Be prepared for some fiddling with sit targets, which will vary depending on how your animations are made.  I tested this for several hours with my alt and was generally pleased with how nicely it worked.  Because I was running two of us on the same machine -- not a top of the line elite machine either -- I found that I had to deal with quite a bit of lag unless we were both using the same set of animations.  I suspect it would be different if I weren't trying to support both of us at the same time, but I haven't yet found a friend to take the place of my alt. 

Share this post


Link to post
Share on other sites

Honestly- you people - scripters - are no less than gods! Sure, with out builders and animators and texture artists SL wd be pretty empty and grey- but you guys give Life.

/me doffs her hat

Share this post


Link to post
Share on other sites

In further testing, I found that the "second" pose ball had a tendency to mess up its rotation when the av on it stood up.  I have cured that by forcing the script to reset on rez or when both avs stand up, and to set both poseballs to ZERO_ROTATION when that happens.  That seems to take care of the problem.  I have updated the Double Walk Lead script in the post above.

Share this post


Link to post
Share on other sites

Tahnks! RL has been hectic this last few days and I haven't atttempted it- I think I can getin tomorrow to try this out. Again- thank you so very much for all you do- and every one else too! Lot's of helpful peeps in the forums.

Share this post


Link to post
Share on other sites

I am trying to get an avatar to pull a plow and one behind the plow pushing it. The avatar pulling it will "control" it so the one pushing is just walking behind, (if that will work). This seems to be close but when I attached the post ball to it and sat the plow went to piecesLiterallyWhat happened. I am not this good a the control scripting mostly I did business programming a long time ago.

Share this post


Link to post
Share on other sites

Sounds like your plow object is physical.  It shouldn't be.

So if you are using the double version of this script, the lead copy would go in the prim you want your "pulling" person to be on, and the second copy would go in another prim.  You'll geet to adjust the sit targets to get them positioned properly with respcet to the plow, of course.  Put your walking and standing anims in both prims and be sure that their names are  in both scripts in the appropriate spots (gWalk and gStand).  Should work fine.

Share this post


Link to post
Share on other sites

No difference, as far the basics of movement are concerned.  After all, it is a non-physical vehicle. :smileywink:  

Share this post


Link to post
Share on other sites

Yup indeed, i suggest for people using this to change the speed a little as follow :) 

 

Line 80 and 86 the vectors change it too 

<-0.15,0.0,0.0>

 

This seems to be more coherent with most walk animations. :matte-motes-delicious:

Share this post


Link to post
Share on other sites

how do i use it? wear the prim or sit on it?

and i have seen a full phantom/ghost  script working fluidly on sl..... is this it?

Share this post


Link to post
Share on other sites

I have a script similar to this Walking through walls script (for different purposes, but this one does the same thing I need help with).    Perhaps someone can explain/help me with an issue.

When on a prim with this script in it, projectiles (objects) that collide with the avatar only generate a collision event from the feet to somewhere above the stomach (lower chest area).   Actually they don't collide with the avatar above this height, they pass right through.

Anybody able to explain this?   Or even better help me make it so collision occurs the entire height of the avatar?

 

Thanks!

 

-- Thor

Share this post


Link to post
Share on other sites

I'm surprised you get collisions at all.  If you really want to detect collisions, you might try setting llVolumeDetect(TRUE).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...