Jump to content

Making a object walk aimlessly


Centbair Daxeline
 Share

You are about to reply to a thread that has been inactive for 2448 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I am working on this little project that the mesh item moves around aimless with in a confine area. Main core is using the llMoveToTarget line and the X and Y positions are base off a random float + the orginal pos. The thing I am having issue is rotations and make it where it doesn't have issue moving up/down slopes. Rotations always been my weakness.

Link to comment
Share on other sites

Here is a snippet for a small area wanderer to give you an idea of how to do it. ...mine is in a large hamster with a seat.

it uses a link message from a seat to start the ride...

you could rez a box, add a touch event, and put the doStuff()  function in that to test.

p.s. I think it only works at ground level, and you need to have pathfinding enabled on your land?

____________________________________

float speed = 2.0;
 vector wanderRange = < 5.0, 5.0, 1.0 >;

debugMsg(string msg)
{//llOwnerSay(msg); //comment this line out to turn off debug messages
}

setup()
{  llDeleteCharacter();
   llResetScript();
}

doStuff()
{   llWanderWithin(llGetPos(), wanderRange, []);
   // llWanderWithin(llGetPos(), <10.0, 10.0, 1.0>, [WANDER_PAUSE_AT_WAYPOINTS, TRUE]);
}
integer k;
integer tog;
integer handle;
integer permtog;
vector startPos;
rotation startRot;
default {

   state_entry()
   {   startPos = llGetPos();
       startRot = llGetRot();
       llDeleteCharacter();
       llCreateCharacter([CHARACTER_DESIRED_SPEED, speed, CHARACTER_ORIENTATION, VERTICAL, CHARACTER_RADIUS, 0.2, CHARACTER_LENGTH, 0.5]);
      // doStuff(); //either replace this with your functionality or replace the function doStuff()      
   }
   link_message(integer sender_num, integer num, string msg, key id)
    {
       if(num == 1)
       {   doStuff();
           llLoopSound("e3f92044-1200-b697-0ef1-784363ed4d5a",1.0);
       }
       else
       {  llExecCharacterCmd(CHARACTER_CMD_STOP, []);
          llStopSound();
          llSleep(0.75);
          llSetPos(startPos);
          llSetRot(startRot);
       }
   }
   on_rez(integer start_param)
   {     llResetScript();
   }
   path_update(integer update, list none)
   {
       if (update == 0) //near goal
       {
           debugMsg("");
       }
       else if (update == 1) //goal reached
       {
           debugMsg("");
       }
       else //errors
       {
           debugMsg("");
       }
       llOwnerSay("Got a pathing failure " + (string)update);         
   }
}

__________________________________________

Edited by Xiija
Link to comment
Share on other sites

You can also consider keyframe motion unless the object absolutely must be physical.

IMO, pathfinding was released with too many limitations and flawed behaviors.

Pathfinding functions, especially llWanderWithin() can randomly lose their mind in a confined space and become unrecoverable even after deleting and creating the character.

Link to comment
Share on other sites

That is most difficult part. Idea I was working on is that it walks around within an area. Once an agent gets in that area, it runs to it. If the agent gets out of the area of the object, it goes back walking around aimless, waiting for another agent come into the contain spot. If that makes sense. I was thinking on Pathfinding, but don't know how well that'll work for what I'm trying to do. 

Link to comment
Share on other sites

On 7/24/2017 at 11:01 PM, Centbair Daxeline said:

I am working on this little project that the mesh item moves around aimless with in a confine area. Main core is using the llMoveToTarget line and the X and Y positions are base off a random float + the orginal pos. The thing I am having issue is rotations and make it where it doesn't have issue moving up/down slopes. Rotations always been my weakness.

you can change rot by doing...  Rot = llEuler2Rot(<0.0 ,0.0, 90.0>*DEG_TO_RAD);

and make the 90.0 part a random float, ... to reverse a rot...   Rot=ZERO_ROTATION/Rot;

for up/down slopes... i dunno, mebbe SetHoverHeight, or one of the ground functions, like llGroundSlope() ?

 

Link to comment
Share on other sites

I have scripted NPCs in the past by using llMoveToTarget and doing a lot of magic with llCastRay to keep track of whatever irregular terrain the object is over, but that's a pain in the  ... whatever.  It doesn't take long before you end up with very heavy code, which means that the chance of making little hard-to-find errors increases.  I agree that pathfinding fell short of Linden Lab's initial hopes, but it is infinitely easier to script characters than doing it the old way.  The major challenge is optimizing the navmesh so that your characters know where they are allowed to go and don't get hung up in tight spots.

Link to comment
Share on other sites

I've found that when pathfinding critters get stuck, this is a good way to help them extricate themselves:

	path_update(integer type, list reserved) {
		if (~llListFindList([PU_FAILURE_INVALID_START,PU_FAILURE_INVALID_GOAL,PU_FAILURE_UNREACHABLE], [type])){
			list l = llGetClosestNavPoint(llGetPos(), []);
			if( l!=[]){
				llNavigateTo(llList2Vector(l, 0), [FORCE_DIRECT_PATH,TRUE]);
			}
			else{
			//Houston, we have a problem... 
			}
		}
	}

 

Edited by Innula Zenovka
Link to comment
Share on other sites

On 7/26/2017 at 0:27 PM, Rolig Loon said:

I have scripted NPCs in the past by using llMoveToTarget and doing a lot of magic with llCastRay to keep track of whatever irregular terrain the object is over, but that's a pain in the  ... whatever.  It doesn't take long before you end up with very heavy code, which means that the chance of making little hard-to-find errors increases.  I agree that pathfinding fell short of Linden Lab's initial hopes, but it is infinitely easier to script characters than doing it the old way.  The major challenge is optimizing the navmesh so that your characters know where they are allowed to go and don't get hung up in tight spots.

With bugs in a heavy script, makes you want to rip your hair out. Most difficult part is avoiding those hang ups on weird collisions that SL throws on old school prims and scupties.

Mmm, never really thought of RC.

On 7/26/2017 at 10:05 AM, Xiija said:

you can change rot by doing...  Rot = llEuler2Rot(<0.0 ,0.0, 90.0>*DEG_TO_RAD);

and make the 90.0 part a random float, ... to reverse a rot...   Rot=ZERO_ROTATION/Rot;

for up/down slopes... i dunno, mebbe SetHoverHeight, or one of the ground functions, like llGroundSlope() ?

 

llGroundSlope(), never heard of that before.

Rotations are always gave me a me a headache

Link to comment
Share on other sites

3 hours ago, Centbair Daxeline said:

Rotations are always gave me a me a headache

Rotations give everyone a headache.  They are real math, which takes practice and good intuition for 3D geometry.  (Persistence and a strong vocabulary help too.)

Link to comment
Share on other sites

Quote

vector dfl_lct;
vector move_lct;
vector trgpos;
key detectedKey = NULL_KEY;
integer dist;
default
{
    state_entry()
    {
        dfl_lct = llGetPos();
        move_lct = llGetPos();
        llSetTimerEvent(1);
        llSensorRepeat("","",AGENT,5, PI, .1);
    }
    timer()
    {        
        if(detectedKey == NULL_KEY)
        {
            float posX = llFrand(10) - 5; //Random number between -5 and 5
            float posY = llFrand(10) - 5; //Random number between -5 and 5
            vector moveTo;
            moveTo = dfl_lct + <posX,posY,0>;
            llMoveToTarget(moveTo,5);
        }
        else llStopMoveToTarget();
    }
    sensor(integer a)
    {
        if (detectedKey)
        {
            dist = (integer) llVecDist(dfl_lct, <trgpos.x,trgpos.y,move_lct.z>);
            if(dist < 5)llMoveToTarget(<trgpos.x,trgpos.y,move_lct.z>,5);
            else detectedKey = NULL_KEY;
            
        }
        else
        {
            detectedKey = llDetectedKey(0);
            llSensorRepeat("",detectedKey,AGENT,5, PI, .1);
            trgpos = (vector)((string)llGetObjectDetails(detectedKey,[OBJECT_POS]));
            dist = (integer) llVecDist(dfl_lct, <trgpos.x,trgpos.y,move_lct.z>);
            if(dist < 5)
            {
                llMoveToTarget(<trgpos.x,trgpos.y,move_lct.z>,5);
                llSay(0,"I see you, " + llDetectedName(0));
            }
        }
    }
    no_sensor()
    {
        if(detectedKey){llSay(0,"Awe, where did you go, " + llKey2Name(detectedKey)); detectedKey = NULL_KEY;}
    }
}

That is what I have so far.

Link to comment
Share on other sites

1 hour ago, Rolig Loon said:

So .... if

if (detectedKey)

is FALSE, does that mean that the device has detected a different avatar?  If it hasn't detected any avatar, of course, the sensor even won't even trigger.  I'm just thinking through the logic.

 

It means if it detects an agent, it goes to it. If that agent is out of the area, it clears out and goes back walking aimlessly. It can only detect one agent so far. It is justan alpha script on trying to get the basic on how it should work.. Well in theory...

Link to comment
Share on other sites

here is a small script that may help show how to choose which way it's facing....

not sure if your timer event being 1 second, and your move being 5 seconds will matter,

also you get the beginning pos, not the current obj pos for your move?...

( drop in a box and touch to start/stop, timer & move both  at 5 seconds)


 

integer k;
vector pos;
vector vPosTarget;
move()
{
      vPosTarget = llGetPos() ;
      vPosTarget.x += llFrand(6.0) - 3.0; //Random number between -5 and 5
      vPosTarget.y += llFrand(6.0) - 3.0; //Random number between -5 and 5    
      llSleep(0.3);
      llRotLookAt( llRotBetween( < 1.0, 0.0, 0.0>, llVecNorm( vPosTarget - llGetPos() ) ), 1.0, 0.5 );
      llMoveToTarget(vPosTarget,5);
      llSetStatus(STATUS_PHYSICS, TRUE);
}
default
{
    state_entry()
    {
        pos = llGetPos();        
        llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y , FALSE);     
        llSetStatus(STATUS_PHYSICS, TRUE);
        llSetHoverHeight(pos.z - llGround(ZERO_VECTOR) + 0.7, FALSE, 1.0);
        llSleep(5);
        llSetStatus(STATUS_PHYSICS,FALSE);
    }
    touch_start(integer total_number)
    {
        if(k = !k)
        {    llSetStatus(STATUS_PHYSICS, TRUE);
             move();
             llSetTimerEvent(5.0);
        }
        else
        {    llStopMoveToTarget();              
             llSetTimerEvent(0.0);
             llSetStatus(STATUS_PHYSICS,FALSE);
        }
    }
    timer()
    { move();
    }
}

 

 

Edited by Xiija
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2448 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...