Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Problems changing object(Player) position on scene load

Discussion in 'Scripting' started by mgcg12, Jul 13, 2018.

  1. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Hi friends,

    so, I have 2 scenes: a village and a dungeon scene. The player starts in the village. The dungeon is accessed by a door(collider that calls Level Manager to change the scene) in the village scene and vice versa.

    On the door, I have put a "Desired spawn position" variable for the player to be in the new scene, when it changes.

    When the player collides with the door inside the dungeon, the desired spawn position is saved on PlayerPrefs, and when the new scene loads, the player script reads the PlayerPrefs and I make a vector3 with the data. I can print these vector3 and they contain the information I want.



    The door script is:
    Code (CSharp):
    1. public class Door : MonoBehaviour {
    2.  
    3.         public Vector3 playerDesiredPosition;
    4.         public int desiredLevel;
    5.  
    6.         // Update is called once per frame
    7.         void Update () {
    8.            
    9.         }
    10.         private void OnTriggerStay(Collider other)
    11.         {
    12.             if (Input.GetKeyDown(KeyCode.Return))
    13.             {
    14.                 setPlayerPosition();
    15.                 LevelManager.doorUsed = true;
    16.                 print("Desired position: " + playerDesiredPosition);
    17.                 SceneManager.LoadScene(desiredLevel);
    18.             }          
    19.         }
    20.  
    21.         private void setPlayerPosition()
    22.         {
    23.             PlayerPrefs.SetFloat("PLAYER_POSITION_X", playerDesiredPosition.x);
    24.             PlayerPrefs.SetFloat("PLAYER_POSITION_Y", playerDesiredPosition.y);
    25.             PlayerPrefs.SetFloat("PLAYER_POSITION_Z", playerDesiredPosition.z);
    26.             PlayerPrefs.Save();
    27.         }
    28.     }
    The problem is: the player changes its position to something a bit random. It's not the position I wanted. It spawns somewhere else in the terrain.

    What could be happening?



    Ps.: the player object has a rect transform, but if I do a transform.position I get the same behaviour

    Ps2: if the default position of the player prefab is near the door, it works. If its far and 20 units up on Y, it doesnt
     
    Last edited: Jul 16, 2018
  2. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Im going mad with this.
     
  3. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Someone please answer me with at least one idea :( i’m almost giving up my first game, I sincerely don't know what to do... I have already tried so many things.
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    797
    hi,

    Formatting your code with code tags help to get more answers: https://forum.unity.com/threads/using-code-tags-properly.143875/.

    - Is there a specific reason you are using UI elements for your character (RectTransform)? If you are using colliders and such, maybe try sprite instead? However I'm not sure if it would make any difference.
    - Also, when using RectTransforms, are you sure you anchors are setup the same way in each scene?
    - Maybe you have two of something (scripts), which messes up your playerDesiredPosition?
    - Is the LevelManager some sort of DontDestroyOnLoad style singleton?
     
    Last edited: Jul 15, 2018
  5. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    426
    PlayerPrefs allows you to save floats.. no need to parse it from a string:

    Code (CSharp):
    1. // saving
    2. PlayerPrefs.SetFloat("PLAYER_POSITION_X", playerDesiredPosition.x);
    3. PlayerPrefs.SetFloat("PLAYER_POSITION_Y", playerDesiredPosition.y);
    4. PlayerPrefs.SetFloat("PLAYER_POSITION_Z", playerDesiredPosition.z);
    5.  
    6. // loading
    7. float playerPositionX = PlayerPrefs.GetFloat("PLAYER_POSITION_X");
    8. float playerPositionY = PlayerPrefs.GetFloat("PLAYER_POSITION_Y");
    9. float playerPositionZ = PlayerPrefs.GetFloat("PLAYER_POSITION_Z");
     
    mgcg12 likes this.
  6. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Thank you so much for your answer, friend!
    Thats nice to know. I changed my code. Still, it doesnt work :(

    Thank you for you answer friend :D
    so, I admit I have no idea why I was using a rect transform. I have removed it and put a normal transform instead. Still, it doesnt work :(

    This is the code in the player script to load the position from the prefs and them apply it. It is being run on Start(), its the last thing there.
    Code (CSharp):
    1.         private void getPlayerPosition()
    2.         {
    3.             if (LevelManager.doorUsed == true)
    4.             {
    5.                 print("door used");
    6.                 transform.position = getDesiredPosition();
    7.                 print("The player position is " + transform.position);
    8.             }
    9.             else if (LevelManager.doorUsed == false)
    10.             {
    11.                 print("Game started, no door used");
    12.             }
    13.             LevelManager.doorUsed = false;
    14.         }
    15.  
    16.         public Vector3 getDesiredPosition()
    17.         {
    18.             float playerPositionX = PlayerPrefs.GetFloat("PLAYER_POSITION_X");
    19.             float playerPositionY = PlayerPrefs.GetFloat("PLAYER_POSITION_Y");
    20.             float playerPositionZ = PlayerPrefs.GetFloat("PLAYER_POSITION_Z");
    21.             Vector3 desiredPosition = new Vector3(playerPositionX, playerPositionY, playerPositionZ);
    22.             return desiredPosition;
    23.         }
    and when I interect with the door inside the cave to leave to the village and the village scene finishes loading, the result of this: "print("The player position is " + transform.position);" IS the desired position I want. But the player is actually in a totally different position.

    I get this: The player position is (-95.0, 1.2, 108.0). Thats the exact desired position. But the player is actually in -58,20,-59. :(

    The original player prefab position in the village is -78,21,-75. Thats very far from the desired position when we're leaving the cave. If I leave this player somewhere near this desired position, it works. Idk why. Doesnt make much sense.

    It works normally when going from the village to the cave. The player goes to the desired position.
     
    Last edited: Jul 16, 2018
  7. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Also, I have tried subscribing my getPlayerPosition to the SceneManager.sceneLoaded delegate, but it has the same behaviour...

    The level manager is a singleton with DontDestroyOnLoad, and its not being destroyed
     
  8. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    426
    I'm assuming you mean in edit mode?

    Can you post an image of what your hierarchy looks like, including the player prefab hierarchy?
     
  9. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Hi Madgvox, thank you for your answer :D

     
  10. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    500
    When you say the player is actually at (-58,20,-59) where is that information coming from? The position field in the Inspector? Because that shows the transform.localPosition, and what you're setting is the global position. If Village has position (0,0,0) and scale (1,1,1), then those will be the same, but otherwise not.
     
  11. mgcg12

    mgcg12

    Joined:
    May 28, 2018
    Posts:
    7
    Hello Errorsatz, thank you for answering :D

    the information is coming from the inspector. But the player isn't a child of any object, so the local position he has is the global position, isnt it? i'll try to set localPos to see what happens

    Edit: setting the localPosition instead gives the same results
     
    Last edited: Jul 19, 2018