Hey guys,
I’m working on a game where you go back to the beginning of the level if you touch a wall. The game is working perfectly, and to respawn i use this C# script:
public void RespawnSphere () {
StartCoroutine(SmoothRespawn());
}
IEnumerator SmoothRespawn () {
isRunning = false;
yield return new WaitForSeconds(1f);
transform.position = spawnPoint.position;
transform.rotation = spawnPoint.rotation;
yield return new WaitForSeconds (1f);
isRunning = true;
}
With this, on contact with the wall, the player stops moving for a second, immediately reappears at the spawn point, and then starts moving again after a second. While this works well, the change of location is too sudden and i would like to make the player gradually move to the spawn point (over the course of a second). I tried using iTween’s MoveTo method, but it didn’t work. This is the code I used:
public void RespawnSphere () {
StartCoroutine(SmoothRespawn());
}
IEnumerator SmoothRespawn () {
isRunning = false;
yield return new WaitForSeconds(0.75f);
iTween.MoveTo (gameObject, new Vector3 (-95f, 1f, 52.5f), 1f);
transform.rotation = spawnPoint.rotation;
yield return new WaitForSeconds (1f);
isRunning = true;
}
The player stops when touching a wall, but doesn’t go back to the spawn point. I think it’s something to do with IEnumerator, but i simply can’t figure it out. I would greatly appreciate it if you could help me. Thanks.
When you call WaitForSeconds, the function is stopped for that amount of time. When you do transform.position = spawnPoint.position after the wait, it will set the position of the player to the spawn point instantly. To get a gradual change, you need to change the position gradually. Here is what you want:
IEnumerator SmoothRespawn () {
isRunning = false;
// Getting the difference in position and rotation
Vector3 deltaPos = spawnPoint.position - transform.position;
Vector3 deltaRotation = spawnPoint.rotation.eulerAngles - transform.rotation.eulerAngles;
// Repeat once per frame for a second:
float timePassed = 0;
while (timePassed < 1.0f) {
// Increment the time to prevent an infinite loop
timePassed += Time.deltaTime;
// Slowly adjust the position and rotation so it approaches the spawn position and rotation
transform.position += deltaPos * Time.deltaTime;
transform.Rotate(deltaRotation * Time.deltaTime);
// Exit the function (it will begin where it left off the next frame)
yield return null;
}
// Ensures the player is exactly where you want him when the time is up
transform.position = spawnPoint.position;
transform.rotation = spawnPoint.rotation;
// Waits for a second after the player has returned before running the game again
yield return new WaitForSeconds (1f);
isRunning = true;
}
Note that if you to change the respawn time from 1 second, you will need to change the speed that you translate and rotate the player. Otherwise, the player will either move past the spawn point and then jump to the correct location or only make it half way before jumping there. To do this, just divide the amount of movement by the respawn time (i.e., transform.position += deltaPos * Time.deltaTime / respawnTime).
Also, an important thing to remember is to include the yield return null inside your while loop. Without it, the loop will complete in one frame and the effect will be the same as you had before. Calling yield will allow Unity to update before the position reaches the destination, resulting in the desired animation.
Rather handle these sorts of tasks in your Update() method than using a co-routine.
Use Vector3.MoveTowards
public Transform target;
public float speed;
void Update() {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
I would recommend using Transform.Translate to move the player. This way you can set the speed and adjust it however you like. You can find that page in the scripting reference here. I’ll type you a code snippet to get you started though 
`
public float speed;
public Transform destination;
public void RespawnSphere () {
StartCoroutine(SmoothRespawn());
}
IEnumerator SmoothRespawn () {
isRunning = false;
yield return new WaitForSeconds(1f);
transform.Translate(Vector3.backwards * speed * Time.deltaTime, destination);
transform.rotation = spawnPoint.rotation;
yield return new WaitForSeconds (1f);
isRunning = true;
}`
Hope this helps!