'Reach target' script : slow down as it gets closer to its target

Hi,

I have made a simple script that would allow me to do two things :

  • Apply the following script to a slave to follow a master’s moves.
  • Have a skybox option that would allow the slave to rotate on Y axis (ex:rotate left) when master moves on X axis (ex: move right). I use it to make a multiscrolling effect and have a good control of multiple layers rotation speed.

My questions are

  • I would like my slave to follow its master with a smooth effect that would slow its speed down as its relative position gets closer to its target. A variable would make that slow effect longer or not. (Ex : Get closer to the target quicker, and slow down at the last moment).
  • Almost the same with smooth rotation : I would like my slave to rotate while its master moves on X axis with a smooth effect that would slow his rotation down when its master would stop moving. A variable would make that slow effect longer or not.

The following script is functional. However, I couldn’t implement the “slow down as it gets closer” effect.

I don’t know if I could explain it well.

Here is my script, would you help me and put me on the right track please?

// Variables -----
var master_obj : Transform; //	 The Master

var moveSpeed : Vector3 = Vector3(1.0,1.0,1.0); //	Move speed

var skyboxMode : boolean = false;	// Use skybox Mode : When master moves on X axis (ex:right), rotate slave on Y (ex:rot left)

var masterMoveXRotateOn : Vector3 = Vector3(0.0,10.0,0.0); // Rotation speed
var lockXAxis : boolean = false; // Disable rotation on that axis

// - - - - - - - - - - - - - Private
private var oldPosition : Vector3; // the position we had last frame
private var oldRotation : Vector3; //the rotation we had last frame


// Functions -----
	
function Start () {	
	

	// Early out if we don't have a target	
	if (!master_obj)
		return;
		
	oldPosition = master_obj.position;		// the position we had last frame
	oldRotation = master_obj.eulerAngles;	//the rotation we had last frame
}


function LateUpdate () {			
		
	if (!master_obj){
		Debug.Log("No Master object specified on " + transform.name);
		return;		
	}
		
	//We may have been moved. Get deltas
	var deltaPosition : Vector3 = master_obj.position - oldPosition;
	var deltaRotation = Quaternion.FromToRotation(oldRotation, master_obj.eulerAngles).eulerAngles;

	oldPosition = master_obj.position;
	oldRotation = master_obj.eulerAngles;
	
	// Skybox Mode
	if (skyboxMode){
			var rot : Vector3 = transform.eulerAngles;
					
			if (!lockXAxis){						
				rot.x = deltaPosition.x * masterMoveXRotateOn.x;			
				transform.Rotate (rot, space);						
			}
	}
	
	var endPosX : float = transform.position.x;
	var endPosY : float = transform.position.y;
	var endPosZ : float = transform.position.z;
	
	if (moveSpeed.x!=0){
		endPosX += deltaPosition.x * moveSpeed.x;		
	}
	
	endPos = Vector3(endPosX, endPosY, endPosZ);	 
	transform.position = endPos;
		
}

Thank you!

1 Like

Use lerps (Vector3.Lerp for positions; Quaternion.Lerp for rotations). If you lerp from the current value to the target value by Time.deltaTime, the effect will be a gradual slow-down as the target value is approached.

Thank you for your answer Laurie.
I had forgotten to add that I had tried doing :

var moveSmooth = 10.0;
....
endPos = Vector3(endPosX, endPosY, endPosZ);	 
    transform.position = Vector3.Lerp(transform.position, endPos,Time.deltaTime*moveSmooth);

without being able to get any gradual slow-down effect.

I was wondering if the error would not come from the fact that I use

oldPosition = master_obj.position;
//We may have been moved. Get deltas
var deltaPosition : Vector3 = master_obj.position - master_oldPosition;
....
endPosX += deltaPosition.x * moveSpeed.x;	
...
transform.position = Vector3.Lerp(transform.position, endPos,Time.deltaTime*moveDamping);

in that case, from my limited understanding of Vectors, I am not sure that endPos represents the good value for a target to be used with Lerp.

My slave doesn’t move the exact distance as the master did from start to end.
It only moves the distance moved during the last frame and ‘Lerps’ on that value only.
So, it Lerps on a very little value and doesn’t keep the same distance with the master.

If someone could take 2 min to take a closer look at my script, that would be a great help.

Thank you!

1 Like