Teleport while Controlling GameObject in Unity3D

Hello :slight_smile:
I am a freshman design student and they’ve asked us to create a game on unity3D without much training on it so needless to say I don’t know much except for the super basic stuff. I don’t know anything about c# and I’ve been having an issue making a gameobject teleport. I’ve spent 6 hours searching for a solution online and the only conclusion I got to was that my object is probably having issues teleporting because of the way I am controlling it - something to do with the controller remembering the last position before the teleport and returning to it. I have no idea how to fix it though. So this is what my scene looks like: I have a sphere as my character, I move it to this other object that has a collider as trigger which then teleports my sphere to a different point (black object) on the terrain. As soon as my object reaches there, it starts sliding back to the point where the teleport happened. I even tried edit > project settings > physics > auto sync transforms as many suggested that and it worked for them.

This is the code by which I control my player:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyPlayer : MonoBehaviour
{
    public float speed = 1;
    public float spacing = 1;
    private Vector3 pos;


    // Use this for initialization
    void Awake()
    {
        pos = transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
            pos.x += spacing;
        if (Input.GetKeyDown(KeyCode.S))
            pos.x -= spacing;
        if (Input.GetKeyDown(KeyCode.D))
            pos.z -= spacing;
        if (Input.GetKeyDown(KeyCode.A))
            pos.z += spacing;


        transform.position = Vector3.MoveTowards(transform.position, pos, speed * Time.deltaTime);

    }
}

and I also have a camera that follows the sphere using this code

using UnityEngine;
using System.Collections;

public class CompleteCameraController : MonoBehaviour {

    public GameObject player;       //Public variable to store a reference to the player game object


    private Vector3 offset;         //Private variable to store the offset distance between the player and camera

    // Use this for initialization
    void Start ()
    {
        //Calculate and store the offset value by getting the distance between the player's position and camera's position.
        offset = transform.position - player.transform.position;
    }
   
    // LateUpdate is called after Update each frame
    void LateUpdate ()
    {
        // Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
        transform.position = player.transform.position + offset;
    }
}

and I have another code on the camera that makes me be able to look around using my mouse

private Vector3 lastMouse = new Vector3(255, 255, 255); //kind of in the middle of the screen, rather than at the top (play)
     private float totalRun = 1.0f;
     void Update()
     {
         lastMouse = Input.mousePosition - lastMouse;
         lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0);
         lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x, transform.eulerAngles.y + lastMouse.y, 0);
         transform.eulerAngles = lastMouse;
         lastMouse = Input.mousePosition;
         //Mouse  camera angle done. 
         //Keyboard commands
         float f = 0.0f;
         Vector3 p = GetBaseInput();
         if (Input.GetKey(KeyCode.LeftShift))
         {
             totalRun += Time.deltaTime;
             p = p * totalRun * shiftAdd;
             p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
             p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
             p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
         }
         else
         {
             totalRun = Mathf.Clamp(totalRun * 0.5f, 1f, 1000f);
             p = p * mainSpeed;
         }
         p = p * Time.deltaTime;
         Vector3 newPosition = transform.position;
         if (Input.GetKey(KeyCode.Space))
         { //If player wants to move on X and Z axis only
             transform.Translate(p);
             newPosition.x = transform.position.x;
             newPosition.z = transform.position.z;
             transform.position = newPosition;
         }
         else
         {
             transform.Translate(p);
         }
     }
     private Vector3 GetBaseInput()
     { //returns the basic values, if it's 0 than it's not active.
         Vector3 p_Velocity = new Vector3();
         if (Input.GetKey(KeyCode.W))
         {
             p_Velocity += new Vector3(0, 0, 1);
         }
         if (Input.GetKey(KeyCode.S))
         {
             p_Velocity += new Vector3(0, 0, -1);
         }
         if (Input.GetKey(KeyCode.A))
         {
             p_Velocity += new Vector3(-1, 0, 0);
         }
         if (Input.GetKey(KeyCode.D))
         {
             p_Velocity += new Vector3(1, 0, 0);
         }
         return p_Velocity;
     }
}

Please let me know if there’s a specific part of my code that I need to edit to resolve this or alternatively if you have a different code that won’t give me this issue, that would make my life so much easier. If I need to edit something or you’re sharing a code, please respond with the complete (corrected) code because otherwise I will just be even more confused.

I know this is a super long post and I am sorry but I am really desperate. It’s been really hard studying online and basically having to teach myself all of this. This is for a final project so I will really appreciate any help you can throw my way. Thank you for reading and thanks for any help in advance.

The above looks like standard movement stuff. I don’t see anything related to teleporting.

Work through some tutorials on movement first, get that working.

THEN move onto something for teleporting. Generally there’s two parts to teleport:

  1. detecting the condition to trigger a teleport (could be a key, a region, a collider, etc.)
  2. updating the player to the new location.

With Unity the code is only a small part of the problem. The rest of it is setting up the scene, and only the tutorial and experience can get you this. All the perfect code in the world won’t work at all with even one thing wrong in the scene.

When debugging your code, to help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

Hello,

Thanks for your reply.
Yes the teleport code is running because I end up teleporting and then I automatically move back to the point in which I teleported from.

This is the teleporting code that is being executed.

using UnityEngine;
using System.Collections;

public class Teleport : MonoBehaviour
{
    public GameObject ui;
    public GameObject objToTP;
    public Transform tpLoc;
    void Start()
    {
        ui.SetActive(false);
    }

    void OnTriggerStay(Collider other)
    {
        ui.SetActive(true);
        if ((other.gameObject.tag == "Player") && Input.GetKeyDown(KeyCode.E))
        {
            objToTP.transform.position = tpLoc.transform.position;
        }
    }
    void OnTriggerExit()
    {
        ui.SetActive(false);
    }
}

You are using “pos” to control the player’s position, but you are not changing it when you teleport.

Try adding a Teleport function to your player and calling that:

public void Teleport(Vector3 newpos)
{
  pos = newpos;
}

and calling it like so:

using UnityEngine;
using System.Collections;
public class Teleport : MonoBehaviour
{
    public GameObject ui;
    public GameObject objToTP;
    public Transform tpLoc;
    void Start()
    {
        ui.SetActive(false);
    }
    void OnTriggerStay(Collider other)
    {
        ui.SetActive(true);
        if ((other.gameObject.tag == "Player") && Input.GetKeyDown(KeyCode.E))
        {
            objToTP.GetComponent<MyPlayer>().Teleport(tpLoc.tranform.position);
        }
    }
    void OnTriggerExit()
    {
        ui.SetActive(false);
    }
}
1 Like

Hello,

Thank you for your response.

I am not sure what you mean by adding the teleport function to my player? where do I add that first bit of code?

And then, once I do this ^ then the new updated teleport code you wrote should replace my current one?

You have a script called “MyPlayer”. Add it to that.

Yes.

OMG Thank you soooooooooo much!!! It worked! You literally saved my vision for this project. I’ve been trying to figure this out for hourssss now. I really appreciate it. Hope you have a love day ahead.

1 Like