Jump to content

Running away "device"


00b02c
 Share

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

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

Recommended Posts

Hey! I decided to try to make such a wearable "device", which would allow when another avatar appears in a certain radius, my avatar starts moving in the opposite direction. As if he was running away from other avatars.

Not sure how logical it sounds ...

I figured I needed to start with a sensor event and a ...

llMoveToTarget(llGetPos() - <some_vector???>, 0.0);

but I got stuck on that. Please tell me where to go next?

 

Well, in the sense of how to run back for about twenty meters and stop until someone approaches again. Or can he push himself away? I know this is a bit wild, but still.

Edited by 00b02c
:)
Link to comment
Share on other sites

Ooh, fun. There are advantages and disadvantages to both, but I generally prefer llSetForce() over llMoveToTarget when possible.

So, what you want to do is apply a force to yourself in a direction facing away from the other avatar. Forces can be thought about like little arrows, that move things form their tail to their head. a force between two points is as simple as

vector force = head - tail;

and in this case the head would be your position, and the tail the position of the person you're running away from:

vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_POS]),0);

but the strength of a force is proportional to how long it is. if you were to use that, you would be pushed very hard when far from your friend, and very little when close by, which is the opposite of what you want. to make things simple you could make the force always the same by setting its length to one (which is called 'normalizing' it) and multiplying by a desired length:

force = llVecNorm(force)*10;

Putting that all together: (untested, I may have bugs.)

default()
{
  state_entry()
  {
    llSensorRepeat("","",AGENT_BY_USERNAME,12,PI,1.0);
  }
  sensor(integer n)
  {
    vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_POS]),0);
    force = llVecNorm(force)*10;
    llSetForce(force,FALSE);
  }
  no_sensor()
  {
    llSetForce(<0,0,0>,FALSE);
  }
}

 

  • Like 2
  • Thanks 2
Link to comment
Share on other sites

9 hours ago, Quistess Alpha said:

Ooh, fun. There are advantages and disadvantages to both, but I generally prefer llSetForce() over llMoveToTarget when possible.

So, what you want to do is apply a force to yourself in a direction facing away from the other avatar.

If the viewer is rlv-enabled, you can also work out the angle through which the avatar is to turn and then get them to face the direction they are moving using llOwnerSay("@setrot')

Edited by Profaitchikenz Haiku
  • Like 1
Link to comment
Share on other sites

12 hours ago, Quistess Alpha said:

Ooh, fun. There are advantages and disadvantages to both, but I generally prefer llSetForce() over llMoveToTarget when possible.

So, what you want to do is apply a force to yourself in a direction facing away from the other avatar. Forces can be thought about like little arrows, that move things form their tail to their head. a force between two points is as simple as

vector force = head - tail;

and in this case the head would be your position, and the tail the position of the person you're running away from:

vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_POS]),0);

but the strength of a force is proportional to how long it is. if you were to use that, you would be pushed very hard when far from your friend, and very little when close by, which is the opposite of what you want. to make things simple you could make the force always the same by setting its length to one (which is called 'normalizing' it) and multiplying by a desired length:

force = llVecNorm(force)*10;

Putting that all together: (untested, I may have bugs.)

default()
{
  state_entry()
  {
    llSensorRepeat("","",AGENT_BY_USERNAME,12,PI,1.0);
  }
  sensor(integer n)
  {
    vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_POS]),0);
    force = llVecNorm(force)*10;
    llSetForce(force,FALSE);
  }
  no_sensor()
  {
    llSetForce(<0,0,0>,FALSE);
  }
}

 

Hey! Thanks so much for the kindly provided script!


It works as it should, I noticed that it even works like a HUD, which is very convenient!

 

I just tested it in a crowded place and it looks pretty funny!

Edited by 00b02c
  • Like 1
Link to comment
Share on other sites

1 hour ago, 00b02c said:

I just tested it in a crowded place and it looks pretty funny!

your next challenge is to mod the script so that the sensor only starts when your avatar is not moving under your manual control. This way you can move yourself normally and when in running away mode you can manually run away in other directions as well

fa way to trigger when to start/stopthe sensor is with:

http://wiki.secondlife.com/wiki/LlTakeControls

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Mollymews said:

your next challenge is to mod the script so that the sensor only starts when your avatar is not moving under your manual control. This way you can move yourself normally and when in running away mode you can manually run away in other directions as well

fa way to trigger when to start/stopthe sensor is with:

http://wiki.secondlife.com/wiki/LlTakeControls

Thank you! I tried this but it doesn't seem to have any effect on me. Something's missing...

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);
    }
    
    run_time_permissions(integer perm)
    {
        llSensorRepeat("", "", AGENT_BY_USERNAME, 12, PI, 1.0);
        
        if (PERMISSION_TAKE_CONTROLS & perm)
        {
            llTakeControls(
                CONTROL_FWD |
                CONTROL_BACK |
                CONTROL_LEFT |
                CONTROL_RIGHT |
                CONTROL_ROT_LEFT |
                CONTROL_ROT_RIGHT |
                CONTROL_UP |
                CONTROL_DOWN |
                CONTROL_LBUTTON |
                CONTROL_ML_LBUTTON,
                TRUE, TRUE);
        }
    }
    
    control(key id, integer level, integer edge)
    {
        integer start = level & edge;
        integer end = ~level & edge;
        integer held = level & ~edge;
        integer untouched = ~(level | edge);
        //llOwnerSay(llList2CSV([level, edge, start, end, held, untouched]));
    }
    
    sensor(integer n)
    {
        vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0), [OBJECT_POS]), 0);
        force = llVecNorm(force) * 10;
        llSetForce(force, FALSE);
    }
    
    no_sensor()
    {
        llSetForce( < 0, 0, 0 > , FALSE);
    }
}

 

Edited by 00b02c
Link to comment
Share on other sites

7 hours ago, Profaitchikenz Haiku said:

If the viewer is rlv-enabled, you can also work out the angle through which the avatar is to turn and then get them to face the direction they are moving using llOwnerSay("@setrot')

A naive implementation of that will have the avatar walk backwards some of the time, and Avatars face the direction they are moving (or backwards if things go wonky) by default anyway.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

9 hours ago, 00b02c said:

Something's missing...

 

you did get some of the pieces in place so good on you. To progress you further then, the next steps  go something like this

set up a global variable integer Flee

when Flee is TRUE the sensor is On. When Flee is FALSE the sensor is Off

 

in the run_time_permissions event

  set Flee to FALSE
  take controls

 

set up a touch_start event. In this event

  toggle Flee TRUE or FALSE on successive touches. Flee = !Flee; (this lets you start/stop Flee mode manually)
  if Flee is TRUE start the sensor
  else Flee is FALSE stop the sensor

 

in the control event

  use integer start (=keydown) to set Flee to FALSE. OnKeyDown you are moving yourself
  use integer end (=keyup) to set Flee to TRUE. OnKeyUp you are not moving yourself
  start/stop the sensor on Flee (as above)

 

set up a attach event

  when script is attached, request permissions
   

  • Thanks 1
Link to comment
Share on other sites

On 10/23/2021 at 1:52 AM, Quistess Alpha said:

There are advantages and disadvantages to both, but I generally prefer llSetForce() over llMoveToTarget when possible.

I'm primarily used to llMoveToTarget because I like the degree of control it gives me, but I'm always looking to expand my skillset.   

How readily can I use llSetForce to maintain a constant and known speed (e.g. I want to run away from someone every time I see them, so I want to move at 5.13 metres a second)?    Or is that a use case for llMoveToTarget and stopping it in the not at target event rather than waiting for damping to cut in? 

Link to comment
Share on other sites

2 hours ago, Innula Zenovka said:

How readily can I use llSetForce to maintain a constant and known speed (e.g. I want to run away from someone every time I see them, so I want to move at 5.13 metres a second)?    Or is that a use case for llMoveToTarget and stopping it in the not at target event rather than waiting for damping to cut in? 

If you are (an attachment on) an avatar on the ground, then set force will probably be fairly consistent for you; you will quickly reach a maximum speed due to friction, and that speed will basically be the same everywhere. the short time to reach maximum speed to me feels a bit nicer than automatically jerking to top speed (testing may be required to determine the maximum speed a priori. )

If you're flying or go over a hill though, well, let's just say space is weird, and there's no air friction in SL.

  • Thanks 1
Link to comment
Share on other sites

29 minutes ago, Quistess Alpha said:

If you are (an attachment on) an avatar on the ground, then set force will probably be fairly consistent for you; you will quickly reach a maximum speed due to friction, and that speed will basically be the same everywhere. the short time to reach maximum speed to me feels a bit nicer than automatically jerking to top speed (testing may be required to determine the maximum speed a priori. )

If you're flying or go over a hill though, well, let's just say space is weird, and there's no air friction in SL.

Thanks.     What I'm not really understanding is how I determine what the maximum speed should be.

In your example, you have

    vector force = llGetPos() - llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_POS]),0);
    force = llVecNorm(force)*10;
    llSetForce(force,FALSE);

I understand what it's doing, but I don't understand the multiplier.     

By what do I multiply llVecNorm(force) if I want to run away at 5.13 metres/second, the default running speed?    Or is this a case for llMove2Target?

 

Link to comment
Share on other sites

26 minutes ago, Innula Zenovka said:

By what do I multiply llVecNorm(force) if I want to run away at 5.13 metres/second, the default running speed?    Or is this a case for llMove2Target?

Yes, if you want an exact speed, llMove2Target would probably do you better, with set force, it's easiest to just guess and check different values for the factor.

  • Thanks 1
Link to comment
Share on other sites

46 minutes ago, Innula Zenovka said:

By what do I multiply llVecNorm(force) if I want to run away at 5.13 metres/second, the default running speed?    Or is this a case for llMove2Target?

Actually, For my own edification, when using llMoveToTarget, what point should I move to and with what tau if I want to move forward (direction <1,0,0>) at 5.13 meters per second?

Do you just use llMove2Target(5.13*llRot2Fwd(llGetRot()),1.0); ? I'd expect that to be a little off due to how the damping works.

Oh and for the force method, Just remembering that you can damp your velocity to a maximum pretty easily:
 

vector vel = llGetVel();

if(vel*vel>= max_speed*max_speed)
{
	llSetVelocity(llVecNorm(vel)*max_speed);
}

 

Edited by Quistess Alpha
Link to comment
Share on other sites

1 hour ago, Quistess Alpha said:

Actually, For my own edification, when using llMoveToTarget, what point should I move to and with what tau if I want to move forward (direction <1,0,0>) at 5.13 meters per second?

Generally, I use llMoveToTarget to move in  the right direction, calculating the tau on the basis my target is much further away than my intended destination, and then stopping and starting things in either one of the *_target events or a timer or whatever is convenient.

Now we've got KFM and pathfinding that technique isn't so necessary, of course, but sometimes it's useful.

float fSpeed = 5.13;// default running speed
float fTau = 2.0;

integer iToggle;

vector 	vTargetPos;

default
{
	state_entry()
	{

	}
	touch_start(integer total_number)
	{
		if(llGetAttached()){
			if(iToggle =!iToggle){
				vTargetPos = llGetPos()+<(fSpeed*fTau),0.0,0.0>*llGetRot();
				llMoveToTarget(vTargetPos,fTau);
				llSetTimerEvent(0.5);
			}
			else{
				llSetTimerEvent(0.0);
				llStopMoveToTarget();
			}
		}

	}

	timer(){
		llStopMoveToTarget();
		vTargetPos = llGetPos()+<(fSpeed*fTau),0.0,0.0>*llGetRot();
		llMoveToTarget(vTargetPos,fTau);
	}
}

 

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1076 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...