Moving an object around

Hi,

I am looking to move an object continuously in a predefined path (i.e. moving round in a circle or along a square path). Does anybody know how to do this.

I also like to stop it moving once the camera gets ahead of it (i.e. once I passed the object, I don’t want it to move). Is there a way of doing this?

tomcat

There’s no single function you can call on this, no.

You’d have to do the path calculation yourself, which can be as simple or difficult as you make your path.

Also depends on your object and type of movement. For example, if it always faces the move direction, then a path can easily be defined by a number of waypoints, pointing the object towards the next using LookAt() and simply moving it continuously in its own forward direction (transform.forward).

Ok, I had something simpler in mind. I like to have objects in specified location on the plane (say location (10,0,10) where the object moves forward 10 units and once it reached then back by 10 units. (Its like walking forward and back). This is my pseudo code (as I don’t know enough Unity APIs to write the script)

time = current_time
fwd-cnt = 0
bkwd-cnt = 0
move = ok
forever
do

 if direction is forward  move is ok
   move fwd
   fwd-cnt =+ 1
   if (fwd-cnt => 10), then direction is back and fwd-cnt = 0
 if direction is bak  move is ok
   move bkwd
   bkwd-cnt =+ 1
   if (bkwd-cnt => 10), then direction is forward and bkwd-cnt = 0
 time = time + 500 milisec

end

As with camera, if I can find the current location of the camera then I can check that against the current location of the object and then set the “move” variable to “not_ok” which then will stop the movement of the camera.

does this work?

tomcat

Has anybody got a tested version or a tutorial on how to do this

tomcat :?:

Hi tomcat

Here’s a very simple script for an object moving back and forth. This has no modifiers for the camera, its just to show an example script and syntax to change an object’s motion. It is written in Javascript.

This code will also not change the facing of the object. It will move 10 units forwards, then backwards, along its z axis, without rotating.

private var direct: int = -1;  // initialize as the opposite direction 
private var count : int = 0;             // make a count variable for object tracking.

function Update () {
	
	if (count == 0 || count == 10)  // if the object position is 0 or 10
		direct *= -1;				// change the direction to its opposite.  
							        // the same as writing:  direct = direct * -1
	
	transform.Translate(0,0,direct);  //move the object 1 unit 
	count += direct; 				 // track the change in position.
	
	
}

Hi Alec,

Thanks. Its what I was looking for. How do I make sure that the object moves 1 unit, every half second? I cant see a reference to time in the script!

tomcat

Ok, I think I should use

transform.Translate(0, 0, Time.deltaTime/2);

to do it. is that right?

tomcat

Because you want the object to move relative to time passing rather than distance traveled, Time.deltaTime is very useful. Here’s a more accurate script:

function Update () {
	
										
	transform.Translate( 0, 0, 2*Time.deltaTime );    // speed; see below
	if (transform.localPosition.z >= 10)              // at position 10...
		transform.rotation = Quaternion.Euler(0,180,0);//face backward
	if (transform.localPosition.z <= 0)               // at position 0....
		transform.rotation = Quaternion.Euler(0,0,0);   // face forward
						 
	
}

What Time.deltaTime does is take the small part of a second that passed since the last frame. If we didn’t modify it, then it would move the object this small amount every frame. Once it all adds up to 1, our object will have moved 1 unit. This also means 1 second will have passed, because the time is where we got our numbers.

So without modifying the number, the object will move 1 unit per second.
Since you want it to move 1 unit per half second, it will move 2 units per second, so we say 2*Time.deltaTime.

Since we’re operating with time now, I changed the script to rotate the object. What’s happening here is that the object moves at a steady 2 units per second (1 per half second) average, and when its z-position hits or passes 100 or 0, the object turns around and goes the other way.

in this example, we use the local z position, meaning “0” is the z position of the object’s parent. If it doesn’t have a parent, then the world origin is “0”

No variables are needed in this example, but you could use some in place of the speed and max distance, to allow changes from the inspector.

Thanks. It now make sense and i smaking my life a little easire. I did look up Quaternion which has a couple of methods (Slerp and Lerp) and was wondering if I can use them to make the calculation for me and do the moving. I mean something like:

var from : Transform;
var to : Transform;
var speed = 0.1;
function Update ()
{
transform.rotation =
Quaternion.Lerp (from.rotation, to.rotation, Time.time * speed);
}

this is the unity code, but I am wondering would it work for this example?

tomcat

Well, in the examples so far, there is no time where the object is not moving. That is, as soon as it reaches the end, it immediately moves in the other direction. When it does this, it is still moving “forward”, but the forward is now facing an opposite way.

What Slerp and Lerp does is make an adjustment over time by interpolating the “from” and “to” aspects.

So, since we are always traveling forward, a similar rotation-over-time will give us an oval-like shape, or even a circle, depending on how fast you want the rotation to be. This may be what you want, or you may want a straight line back and forth.

If you want it to be a straight line back and forth, it’s still possible to use Quaternion.Lerp, but we should probably stop the object first, and let it turn around over time, before moving it again to the next position.
There are also methods to Lerp the position, so that it moves from one spot to another over time, slowing as it reaches the end.

If you want it to be Oval, then Quaternion.Lerp should be fine, but we will have to change our rotations, or it will probably make a ribbon of “S” shapes instead of an oval.

Thanks Alec. For the straight line I would use what you mentioned earlier. Although Lerp sounds like a good idea, its effect may be a little unpredictable.

tomcat

I think once you get used to the idea, you’ll find a lot of uses for Lerp, and it’ll come more naturally to you.

Here’s another take of Alec’s “move back and forth” script example from a few posts back. This one checks the objects position and then sends it back the other way when it reaches a specific point (eg. enemyPos >= 2.5). Also it flips the direction with a -1 or 1 instead of rotating the object with Quaternion.Euler which I heard somewhere can be slow.

private var trans : Transform;
private var dir : int = 1;
var speedMult : int = 2.0;

function Awake () {
	trans = transform;
}

function Update () {
	var moveSpeed = speedMult*Time.deltaTime;
	enemyPos = transform.localPosition.z;
	
	trans.Translate(0, 0, moveSpeed*dir);
	if(enemyPos >= 2.5)
		dir = -1;
	if(enemyPos <= 1)
		dir = 1;
}

Hi!!!
I´m using this example to give motion to my 3D animal… but do you know hoow can i make it to stop moving when it reaches de point 10 in z, and after 5 secons or so , start moving to the other side?
Thanks


function Update () {

transform.Translate( 0, 0, 2*Time.deltaTime ); // speed; see below
if (transform.localPosition.z >= 10) // at position 10…
transform.rotation = Quaternion.Euler(0,180,0);//face backward
if (transform.localPosition.z <= 0) // at position 0…
transform.rotation = Quaternion.Euler(0,0,0); // face forward

}