Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Move Object in a Square Motion...and Repeat

Whiplash Pogelmann
Registered User
Join date: 26 Aug 2006
Posts: 5
02-16-2007 14:08
I wish to move a single object, in a square motion so that once it completes it's move, at the end of it's fourth move, it is right back where it started from.

So here is what I have so far....I know I'm far from perfect on this one.

CODE

integer Target;

default
{

touch_start(integer num)
{

llSetStatus(STATUS_PHYSICS, 1);

llSetTimerEvent(0.2);
Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + <0, 10, 0>, 1);
llSleep(5);

Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + <10, 0, 0>, 1);
llSleep(5);

Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + <0, -10, 0>, 1);
llSleep(5);

Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + <-10, 0, 0>, 1);
}
}



It does work, but here are the problems:

1. I need to get away from using llSleep so that it "flows" better and is easier to program distance changes and not have to also program the timing llSleep changes.

2. I want to *safely* have it repeat the process over and over. I mention safely so that it doesn't get "caught" in a poorly programmed loop just for the sake of repeating itself.

3. If I really get this thing moving fast, and it's a small prim, I'd like to have some way to stop and start it on a /channel (without an open listener in order to minimize any lag). I plan to have more than one running...it's fine it they all stop and start using the same channel....just haven't used this function before.

Listing specific code examples is ok as I've been playing around with this all day and haven't made any "giant" leaps forward with in in a while. I did minimize the code so it is as clear as possible to read.

I'm very open to suggestions...thanks in advance!
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
02-16-2007 15:04
This should get you into a timer Event and give you a 'safe' loop...

CODE
list Targets = [<0, 10, 0>, <10, 0, 0>, <0, -10, 0>, <-10, 0, 0>];
integer Target;
integer Turn;

default
{
touch_start(integer num)
{
if (! llGetStatus(STATUS_PHYSICS))
{
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(5);
}
else
{
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(0);
}
}

timer()
{
Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + llList2Vector(Targets, Turn), 1);
Turn += 1;
if (Turn >= 3) Turn = 0;
}
}
Now you just need to have a look at the listen Event. :D
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
02-16-2007 15:06
You could switch to using lists and timers or possibly states, one for each leg.

EDIT: Pale beat me to it.
Whiplash Pogelmann
Registered User
Join date: 26 Aug 2006
Posts: 5
02-17-2007 07:23
Thanks for the awesome replies!

Here is the program I'm using with three mods as noted below:

CODE

list Targets = [<0, 20, 0>, <20, 0, 0>, <0, -20, 0>, <-20, 0, 0>];
integer Target;
integer Turn;

default
{
touch_start(integer num)
{
if (! llGetStatus(STATUS_PHYSICS))
{
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(2);
}
else
{
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(0);
}
}

timer()
{
Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + llList2Vector(Targets, Turn), 1);
Turn += 1;
if (Turn >= 4) Turn = 0;
}
}


You'll note I made a few changes...

1. if (Turn >= 4) Turn = 0;
As the original 3 wasn't completing the fourth side.

2. list Targets = [<0, 20, 0>, <20, 0, 0>, <0, -20, 0>, <-20, 0, 0>];
AND
llSetTimerEvent(2);
I made these two changes as it would move, then slow down and then finally begin the next leg of the movement.

The "20" forces a big move while the timer doesn't let it complete the move to minimize or even remove the slow down problem.

3. I turned Phantom on for the prim so it doesn't get knocked around and such.

PROBLEM:

However, it's unpredictable. I leave it running for just 5 minutes and it's moved from it's original location.

SOLUTION?

I need as low lag as possible, but I need it to be precise, otherwise the thing ends up off the property.

Thoughts?
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
02-17-2007 08:50
yes, ...4 not 3... oops :o

I did almost add a note at the time that I avoid physical objects because what with the lag, and well... the physics, they tend to have a mind of their own.

I suspect that unpredictability comes with the territory.

<watches as his object disappears over the horizon>

The only thing I can suggest is that you periodically do a non-physical, llSetPos, type adjustment to bring the object back to some point of origin based on an initial llGetPos in the touch_start perhaps?

But it may be noticeable in the movement.
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
02-17-2007 11:40
Don't use llGetPos() over and over. use it once at the beginning to get the original starting position. Then reuse that value. Each four turns, it will attempt to go back to the start.
Whiplash Pogelmann
Registered User
Join date: 26 Aug 2006
Posts: 5
02-17-2007 12:20
Thanks for the ideas....I'm looking at a door script of mine for ideas on how to best use the LLGetPos().
Whiplash Pogelmann
Registered User
Join date: 26 Aug 2006
Posts: 5
02-17-2007 13:09
Still no good...I even hard coded the start position...
CODE

list Targets = [<0, 20, 0>, <20, 0, 0>, <0, -20, 0>, <-20, 0, 0>];
integer Target;
integer Turn;
// vector Start_Position;
vector Start_Position = <230.060,225.233,23.225>;

default
{
touch_start(integer num)
{
if (! llGetStatus(STATUS_PHYSICS))
{
// Start_Position = llGetPos();
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(2);
}
else
{
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(0);
}
}

timer()
{
Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + llList2Vector(Targets, Turn), 1);
Turn += 1;
if (Turn >= 4)
{
Turn = 0;
llSetPos(Start_Position);
}
}
}

You can see where I //commented out the ||GetPos and put in a hard coded position, but this thing still doesn't go back to it's start position for some reason.

Any advice is helpful....
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
02-17-2007 13:54
hehe... I've had a little play with it myself. I've got mine moving in a rather smaller square (I got tired of chasing the damn thing all over the place :p) so you may need to re-tune it.

CODE
list Targets = [<0, 2, 0>, <2, 0, 0>, <0, -2, 0>, <-2, 0, 0>];
integer Target;
integer Turn;
vector StartPos;

Move()
{
if (Turn >= llGetListLength(Targets))
{
Turn = 0;
llSetStatus(STATUS_PHYSICS, FALSE);
llSetPos(StartPos);
llSetStatus(STATUS_PHYSICS, TRUE);
}

llSetText((string)Turn, <0, 0, 0>, 1);
Target = llTarget(llGetPos() + <0, 0, 30>, 0.1);
llMoveToTarget(llGetPos() + llList2Vector(Targets, Turn), 1);
Turn += 1;
}

default
{
touch_start(integer num)
{
if (! llGetStatus(STATUS_PHYSICS))
{
Turn = 0;
StartPos = llGetPos();
llSetStatus(STATUS_PHYSICS, TRUE);
Move();
llSetTimerEvent(5);
}
else
{
llSetText("off", <0, 0, 0>, 1);
llSetStatus(STATUS_PHYSICS, FALSE);
llSetTimerEvent(0);
llSetPos(StartPos);
llSetRot(<0.0, 0.0, 0.0, 1.0>);
}
}

timer()
{
Move();
}
}
I also restructured it just a little because I found it more convenient to have the timer code in a function but it's essentially still the same thing.

The only thing you've really missed is that llSetPos only applies to non-physical objects.