- Home /
how retrieve final player position in previous scene after switching from a new scene? in 2d rpg
Can someone help me to solve my problem? After switching from a new scene, i want my player position to be near to the entry point in the previous scene where i switch to a new scene via door (BoxCollider).
Here is my sample code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SwitchingScene : MonoBehaviour
{
//designing entry and exit point for the scene switching
public string nextScene;
public string enter;
public string exit;
public void OnTriggerEnter2D(Collider2D col)
{
//or (col.CompareTag("Player")
if (col.gameObject.tag == "Player")
{
SceneManager.LoadScene(nextScene);
}
}
// designing entry and exit point for this script:
// if player position collider with the intial object(enter), it will enter a new scene.
// if the player went and collide with another object(exit),
// it will return back to its intial position(enter) from previous scene. (Unload scene?)
}
Can you help me to code this logic or show a better way to retain the player final position in the previous scene? Thank you.
Answer by bhavinbhai2707 · May 05, 2018 at 03:42 PM
The best way is to Store the location of player just before you change the scene!!
if (col.gameObject.tag == "Player")
{
Vector2 tempPos = player.transform.postion;
SceneManager.LoadScene(nextScene);
}
and simply handle the data between scenes using a static script!! Click Here
to know more about static scripts
$$anonymous$$aybe a better solution than $$anonymous$$e, which uses PlayerPrefs ;)
Thanks for the reply. A follow up question, can this code apply to singleton player ? If not, do i need to make duplicate player for each scene i make?
(PS : is singleton and static the same thing?)
Thank you.
Answer by Koyemsi · May 05, 2018 at 03:47 PM
A simple way would be to store the player's last position in the PlayerPrefs, then load it at the start of the new scene. 2 ways to do this :
Store x, y and z pos with floats (vector3 cannot be saved in PlayerPrefs).
Store it as a cleaner Vector3 using JSON and serialization. Take a look at this clever tuto (sorry it's in french but the code's quite easy to understand) https://www.esprit-unity.fr/enregistrer-des-donnees-avec-playerprefs/
Actually i may not recommend using Playerprefs for storing this type of data, PlayerPrefs should only be used for storing essential Information like Scores,settings,names etc!! its better to handle your kind of data inGame ins$$anonymous$$d of storing outside!!
Answer by Pinkuboxu · May 05, 2018 at 04:58 PM
Are you using a Game Manager to persist data between scenes? I think the general method is to make a Game Manager Object and give it a script that you call DontDestroyOnLoad in. You can make data persist between scene calls inside this script and reference it from another script by getting the scripts component as long as the fields (or methods) are made public.
Yep, i went and check online to see how to avoid making duplicate player object when using DontDestroyOnLoad while switching scene. (PS: i still havent decide to use 'singleton', 'dontdestroyonload' or ''static'' for my player object when switching scene) (PSS : Are singleton and static the same thing? If they are, how do i prevent them from intefering with another different unplayable scene such as Credit?)
But my real question is, how do i able to make the player object spawn at the correct location in Town where they are many houses (entry and exit point) to collide? And how avoid player spawn at the starting point of the game?
Sorry for the long comment, but i am really passionate to know. Thank you.
They are not the same. The singleton pattern contains a static reference to the object itself. A better way of defining it is that it restricts the instance to only one object and will deny any other versions of the object (Your Game$$anonymous$$anager) from existing. As for the PS, You don't have to decide among the three as you will have to use them all in some capacity for between scene persistence. It's a way to have global persistent data. Singletons are fine as long as you are using them sparingly and aren't trying to use them in any multi-threading situations, which you may never even have a need for threading anyway. For your PPS you'll simply have to make sure you disable or destroy any unused objects that you don't want running at any given time, which you should be doing anyway. Don't leave the stove burning when you are going out. For instance, if you have AI running patrol when the player can't even see them... maybe disable that until the player is close enough. You don't have to make duplicates in the scenes, rather you can instantiate your prefabs and get data from your Game$$anonymous$$anager to set the previous information or better just make sure the game object has DontDestroyOnLoad and just disable the persistent object when you don't need it so that it is still there for when you do need it, or just destroy it outright if you don't really need it anymore.
If you have a town setting with interiors and and an exterior, say like Skyrim, each door should have a transform for where the player should spawn on the other side. Easiest setup I can think of is to make a single door prefab with a transform at the position you wish the player to spawn at upon transitioning. You make a script for that one prefab door that points in some way to the instance of this door prefab in the other scene or area. It's off topic from what you asked in this thread so you may want to ask another question if you need a more in depth explanation on how to make door transitions. Also, you should look into the idea that you can actually load a scene into a current scene without eli$$anonymous$$ating any of the currently loaded scene. Research the Scene$$anonymous$$anager
@unity_YBW262B1IWmeXw, if your levels have several entry and exit points, may be you should consider not storing the player's position by its coordinates. The idea would rather be to store a reference to the exit door that was collided. The script has to know which is the corresponding entry point in the next level. So you may store in a List or Array all the matching pairs of doors. Alternatively, your code could deter$$anonymous$$e the matching entry door by analyzing the name of the exit door that was used; all your doors should be named sequentially in each level, so that the ExitDoor1from level 1 leads to EntryDoor1 in level 2. Whatever the levels, ExitDoor n would always lead to EntryDoor n in the next level. $$anonymous$$nowing which door leads to which, you would simply spawn your player at the transform position of the entry door. Not sure if my explanations are clear...
It's clear but probably more complicated than need be and doesn't solve the issue of the doors collision that they asked about unless you offset the graphic and the collider from the door objects transform or by creating another empty inside of the door object as a child so you have a relative transform. That transform's offset can also be changed in the inspector with a serialized field to compensate if you need fine tuning of the spawn position without affecting the position of the door object and keeping all your doors instances of one door prefab you just drop into your world during level design.
The idea of the List would work but you would need a door manager object or a class inside of the persistant game manager to keep track of that List and allow it to persist. Again, it's fine and I think I understand your implementation, but I think it's less elegant.
The second idea is more elegant but the two doors don't have to be named sequentially, rather just name the, two door halves(?), exactly the same, as they are virtually the same door. Save the shared name of the doors in your persistant game manager (for example public string doorName;) before the scene transition, then use GameObject.Find(doorName) after the scene transition is done. Just don't spawn them at the transform of the door, use a second child transform then they won't bump into the collider of the door like they asked about.
Answer by unity_YBW262B1IWmeXw · May 07, 2018 at 01:19 AM
Thank you for your generous advices, I have found a video on youtube that describe your single prefab door as warp points.
https://www.youtube.com/watch?v=Ra01vCUG4-o
I hope by changing scene, we too also can transform the preferable location of the player between scene. Hope this would help and please do leave a comment if you meet with any problem.
Thank you.