Home > OS >  When loading the main menu scene in Unity, I need the player position to reset even if there's
When loading the main menu scene in Unity, I need the player position to reset even if there's

Time:12-22

I need to reset the player's position in the main menu scene to 0,0,0, whether or not they have saved their playerprefs.

This is the code I'm using in Unity to reset the player's position when they exit to the Main Menu scene. This is a VR game. It works for players who haven't saved, but doesn't reset the position of players who have saved their playerprefs, and I don't know how to make that happen.

My reset position script:


//reset position of player in main menu scene
[SerializeField] Transform playerSpawnPosition;
[SerializeField] GameObject player;
[SerializeField] private Camera playerHead;
public void ResetPosition()
{
   var rotationAngleY = playerHead.transform.rotation.eulerAngles.y 
                        - playerSpawnPosition.rotation.eulerAngles.y;
       
   player.transform.Rotate(0, -rotationAngleY, 0);
    
   var distanceDifference = playerSpawnPosition.transform.position 
                            - playerHead.transform.position;
       
   player.transform.position  = distanceDifference;
}

   public void ExitToMainMenu(){
      
      if(pauseMenu == null){
         return;
      }
      pauseMenu.SetActive(false);
      if (LeftHand && RightHand)
      {
         Time.timeScale = 1f;
         LeftHand.transform.parent = leftparent;
         RightHand.transform.parent = rightParent;
      }
      
      SceneManager.LoadScene(0,LoadSceneMode.Single);
      
      ResetPosition();
      
   }

My Save Player Position script:


public void SavePlayerPosition(){
   hpc = FindObjectOfType<HVRPlayerController>();
   if(hpc == null){
      return;
   }
   PlayerPrefs.SetFloat("PlayerXPos",hpc.transform.position.x);
   PlayerPrefs.SetFloat("PlayerYPos",hpc.transform.position.y);
   PlayerPrefs.SetFloat("PlayerZPos",hpc.transform.position.z);
   Vector3 v = hpc.transform.rotation.eulerAngles;
   PlayerPrefs.SetFloat("PlayerYRot",v.y);
   
   PlayerPrefs.SetString("SpawnId", "xyzSave");
   Debug.Log("Saved player to position "   hpc.transform.position.x   " "
        hpc.transform.position.y   " "  hpc.transform.position.z   " ");
}
public void LoadPlayerPosition(){
   hpc = FindObjectOfType<HVRPlayerController>();
   if(hpc == null){
      return;
   }
   playerX = PlayerPrefs.GetFloat("PlayerXPos");
   playerY = PlayerPrefs.GetFloat("PlayerYPos");
   playerZ = PlayerPrefs.GetFloat("PlayerZPos");
   playerYRot = PlayerPrefs.GetFloat("PlayerYRot",hpc.transform.rotation.y);
   Debug.Log("Loaded player position "   playerX   " "
        playerY   " "  playerZ);
}

CodePudding user response:

You're likely calling LoadPlayerPosition() after every position reset. If it's called in a Start() method in a monobehaviour, it's likely going to get called after ResetPosition().

If this is the case, the 0,0,0 values for your players position might not even be set by ResetPosition, instead they're set to the default values returned by PlayerPrefs.GetFloat(), '0.0'.

To Test

Put breakpoints on ResetPosition(); and hpc = FindObjectOfType<HVRPlayerController>();. In the case where a player has set player prefs, I have a feeling your will observe that ResetPosition(); is called before hpc = FindObjectOfType<HVRPlayerController>();.

To Fix

This is a bit tricky. The solution I'd play around with is tying the two functions together in another function call. The function would have a parameter isMainMenuReset. If it's true, call ResetPosition(), else, call LoadPlayerPosition(). You'd have to replace all LoadPlayerPosition() calls in your codebase with this new function call.

  • Related