What I want is to be able to (press left/right) and move my object to another object (or Vector3 position).
With the code
var target:Transform;
var smooth = 0.8;
function Update () {
transform.position = Vector3.Lerp (transform.position, target.position, Time.deltaTime * smooth);
}
I can move the object towards one target, and ease out the speed (fine so far), but if I want to move further to another and third object, if I press the left/right keys.
Example: targets
1 2 3 4 5
So if I start at 1, pressing right brings me to target 2, pressing right again to target 3 and if pressing left, then back to 2…
You need some sort of array to iterate through, I made a simple script doing this:
#pragma strict
enum REPEAT {
Yes,
No
}
var repeat : REPEAT = REPEAT.Yes; //Set the default enum value
var waitForFinish : boolean = true; //Wait for acceptable range to continue
var finishArea : float = 0.5; //The range for testing if object is close
var locations : Vector3[]; //An array with Vector3 locations in world space
var currentLocation : int = 0; //The current location in the array
var speed : int = 2; //The speed of the moving object
private var myTransform : Transform; //Cache the transform as an optimization
function Start () {
myTransform = transform; //Set myTransform to object's transform component
}
function Update () {
if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.RightArrow)) CheckInput(); //Check if the user has given input
myTransform.position = Vector3.Lerp(myTransform.position, locations[currentLocation], speed*Time.deltaTime); //Lerp to new locations in the array
}
function CheckInput () {
if (waitForFinish) {
var sqrLen = (myTransform.position - locations[currentLocation]).sqrMagnitude; //Using sqrMagnitude to check if the object is in close range
if (sqrLen > finishArea) return; //If it isn't then exit the function
}
if (Input.GetKeyDown(KeyCode.LeftArrow)) currentLocation--;
if (Input.GetKeyDown(KeyCode.RightArrow)) currentLocation++;
switch (repeat) {
case REPEAT.Yes:
if (currentLocation<0) currentLocation=locations.Length-1; //Set the location in the array to the number of objects in the array
currentLocation = currentLocation%locations.Length; //Repeat when exhaust all objects
break;
case REPEAT.No:
currentLocation = Mathf.Clamp(currentLocation, 0, locations.Length-1); //Clamp the value if we don't want the position to loop through the array
break;
}
}
}
Also added an enum for repeating or clamping (this could be a boolean, but if you want some other sort of logic to the iteration through the array this is a good start). The waitForFinish is a boolean for testing the acceptable close range to continue to the next Vector3 in the array and the finishArea is the range for that.
If you want to target existing positions of GameObjects then change the Vector3's:
var locations : Vector3[]; to var locations : Transform[];
So here's another version of the earlier posted script. Here you can choose between Unity's moving algorithms at runtime to see which one you think fits the best to your implementation.
Keep in mind that the speed variable differs between them.
#pragma strict
enum REPEAT {
Yes,
No
}
enum MOVEMENTTYPE {
Lerp,
SmoothDamp,
SmoothStep,
MoveTowards
}
var repeat : REPEAT = REPEAT.Yes;
var movementType : MOVEMENTTYPE = MOVEMENTTYPE.Lerp;
var waitForFinish : boolean = true;
var finishArea : float = 0.5;
var locations : Vector3[];
var currentLocation : int = 0;
var speed : int = 2; //Keep in mind speed differs depending on selected MOVEMENTTYPE
private var currentVelocity : Vector3 = Vector3.zero;
private var myTransform : Transform;
function Start () {
myTransform = transform;
myTransform.position = locations[currentLocation];
}
function Update () {
if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.RightArrow)) CheckInput();
myTransform.position = MoveMe(myTransform.position);
}
function CheckInput () {
if (waitForFinish) {
var sqrLen = (myTransform.position - locations[currentLocation]).sqrMagnitude;
if (sqrLen > finishArea) return;
}
if (Input.GetKeyDown(KeyCode.LeftArrow)) currentLocation--;
if (Input.GetKeyDown(KeyCode.RightArrow)) currentLocation++;
switch (repeat) {
case REPEAT.Yes:
if (currentLocation<0) currentLocation=locations.Length-1;
currentLocation = currentLocation%locations.Length;
break;
case REPEAT.No:
currentLocation = Mathf.Clamp(currentLocation, 0, locations.Length-1);
break;
}
}
function MoveMe (newCoord : Vector3) {
switch (movementType) {
case MOVEMENTTYPE.Lerp:
newCoord = Vector3.Lerp(newCoord, locations[currentLocation], speed*Time.deltaTime);
break;
case MOVEMENTTYPE.SmoothDamp:
var smoothTime : float = 0.1;
newCoord = Vector3.SmoothDamp(newCoord, locations[currentLocation], currentVelocity, smoothTime, speed, Time.deltaTime);
break;
case MOVEMENTTYPE.SmoothStep:
newCoord.x = Mathf.SmoothStep(newCoord.x, locations[currentLocation].x, speed*Time.deltaTime);
newCoord.y = Mathf.SmoothStep(newCoord.y, locations[currentLocation].y, speed*Time.deltaTime);
newCoord.z = Mathf.SmoothStep(newCoord.z, locations[currentLocation].z, speed*Time.deltaTime);
break;
case MOVEMENTTYPE.MoveTowards:
newCoord = Vector3.MoveTowards(newCoord, locations[currentLocation], speed*Time.deltaTime);
break;
}
return newCoord;
}
function OnDrawGizmos () {
if (locations.Length>0) {
for (var i = 0; i < locations.Length; i++) {
Gizmos.color = Color.yellow;
Gizmos.DrawWireCube (locations*, Vector3(.5,.5,.5));*
*}*
*}*
*}*
*```*