This functionality is covered in the RPG series (Combat course), and is not really simple. In the course they are called ‘portals’
First, the trigger code should not be on the player, but on the triggers themselves. Each trigger need some way of specifying which trigger it links to in the other scene. This is because in theory you will almost always have 2 triggers in each scene; the ‘entrance’ and the ‘exit’. You’d link an exit in scene A with an entrance in scene B. The first and last scenes are exceptions. When the player enters a trigger, you want to do a few things;
- Add this trigger to
DontDestroyOnLoad
. This is because as soon as the new scene loads, this trigger is destroyed and it stops executing. We don’t want this, yet, because there are still things we want to do. Unfortunately, this also means that the triggers must be first-level objects in the hierarchy of the scene. They cannot be a child of any other object.
- Find the trigger that is linked to this one
- Move the player to it. You may want to set a ‘spawn position’ for each trigger so that the player isn’t moved into the trigger and activates it again. This will cause the scenes to jump back and forth rapidly and you will have a hard time getting out of it. Set a spawn location just outside the trigger
- Now you can destroy this trigger because we no longer need it
Be aware that when you go from scene A to scene B and then back to scene A, scene A will be back in it’s original state. This means any enemies you killed will be alive again, any coins you picked up will be there again, etc. This ‘scene persistence’ is also covered in the RPG series.
This is basically the script you want
// Written in Post, so may have plenty of typos
public enum PortalIdentifier { A, B, C } // you can add more if you have more portals
public class Portal : MonoBehaviour
{
[SerializeField] string _targetScene;
[SerializeField] PortalIdentifier _identifier;
[SerializeField] Transform _spawnLocation;
private bool _alreadyTransitioning = false;
private void OnTriggerEnter2D(Collider2D other)
{
// If it's not the player, ignore it
if (!other.CompareTag("Player"))
return;
// If we're already transitioning, ignore it
if (_alreadyTransitioning)
return;
// Start the transition
_alreadyTransitioning = true;
// Add the portal to DDoL
DontDestroyOnLoad(gameObject);
// Load the new scene
SceneManager.LoadScene(_targetScene);
// Find the linked portal
Portal linkedPortal = default;
foreach(var portal in FindObjectsOfType<Portal>())
{
if (portal._identifier != this._identifier)
continue;
linkedPortal = portal;
break;
}
// If we found a linked portal, move the player to it
if (linkedPortal != null)
playerTransform.position = linkedPortal._spawnLocation;
// Now we can destroy this portal
Destroy(gameObject);
}
}
Now, you will set your exit ‘portal’ in scene A to have an identifier ‘A’ and your entrance portal in scene B to also be ‘A’. This will link them and then your player will move from the exit in scene A to the entrance in scene B. If you go back through the entrance in scene B, it will link back to the exit in scene A. Each portal in the scene must have unique identifiers, so the exit in scene B will have identifier ‘B’ and link to entrance ‘B’ in the next scene