Can't manually set position of character

Hi
I’m having trouble setting the position of my character, who has a character controller. I have made a trigger, that sets a UI fade animation, and an animation event that calls the teleport method. I have used Debug.Log to check if these methods are being called, which works, and it seems like the character teleports to the destination for about one frame, before being teleported back to the original position. I have also tried using a button to do it without the trigger, in case that was the issue, but it made no difference. Here’s my code:

    public void Teleport()
    {
        Debug.Log("Teleporting");
        Debug.Log(transform.position);
        if (SceneManager.GetActiveScene().buildIndex != TeleportScript.MapNumber)
        {
            SceneManager.LoadScene(TeleportScript.MapNumber);
        }
        transform.position = Spawn;
        Debug.Log(transform.position);
    }

Spawn is a vector 3 for the position. I am completely sure that this function is being called, and the last Debug.Log does show that the player’s position is equal to the spawn destination, but the player does not move, which is why i think it teleports back to the original position.

Thank you for your help!

Another part, or a later part of the same script, is likely overwriting the position based on an old value. You already printed the relevant information and told us that this function is getting called, so it is not the problem.

1 Like

Try disabling the CharacterController, changing the transform.position, then re-enabling the CC.

Or even the entire GameObject if that’s easier and you have the reference. Just beware that ALL coroutines running on that GO will die.

1 Like

This is VERY strange. Disabling the CharacterController, moving the character and re-enabling worked, like you said (thank you!), but, I have a game I’ve been working on for many years and it wasn’t until now that the CharacterController wouldn’t allow me to reposition the GameObject it’s attached to. This is brand new.

Yes, CharacterController overrides the transform position. You’ll either need to disable it before setting the new position, or maybe setting it in LateUpdate to override CharacterController code that runs in Update (LateUpdate is called after Update). I’d just create an extension method:

public static class CharacterControllerExtensions
{
    public static void TeleportTo(this CharacterController controller, Vector3 position)
    {
        controller.enabled = false;
        controller.transform.position = position;
        controller.enabled = true;
    }
}

// usage:
myCharacterController.TeleportTo(new Vector3(10,0,10));

Like Nad says, you can change the transform position without disabling the character controller if you do the change after calling CharacterController.Move. Although I just did a little test and it seems you don’t necessarily have to wait for LateUpdate.

    void Update()
    {
        cc.Move(velocity*Time.deltaTime);
        if (Input.GetKeyDown(KeyCode.Q))
            transform.position+=transform.forward*10;   // teleport forwards
    }
1 Like