In most games, a warp point that loads a new scene is tied to an other warp point in the scene in question. You don’t just pop up at (0, 0, 0) or at some random location, you appear where it makes sense for you to appear. If you open the door from the restaurant to the kitchen, the kitchen scene loads and here you are with the door from the kitchen to the restaurant in your back. That’s how you make game worlds feel like real, connected places.
I assumed designing/coding that would be fairly straightforward. As it turns out, it isn’t. I remember RPG Maker 2003 having a built-in system that handled exactly that, and that possibly fed into my naivety. So… What would actually be the best way to “link” two warp points? Remember, the issue is that the warp points are on different scenes. Hopefully it can be done without relying on tags or string fields; those are highly error-prone and annoying to maintain…
I did notice you made this stipulation though. Which can be a problem since you need some token to associate the teleport points in each scene.
For our projects we did just use strings:
(In Greenhouse scene)
(In garden scene)
But if you don’t want strings because they’re error prone.
You can really just use any ‘token’ you want.
You could create a ScriptableObject that acts as the token. Create instances of it in your assets folder. You could even put variables on it that hold more information for spawning than just the association.
Then on your “load scene” and “scene loaded” scripts you just have a field that is the type of this SO and drag on the necessary token that associates the 2.
…
But yeah something like this (very simple solution):
[CreateAssetMenu(fileName="TeleportToken", menuName = "ScriptableObjects/TeleportToken")]
public class SceneTeleportToken : ScriptableObject
{
//stick in some variables if you want to
}
public class GameManager
{
public static SceneTeleportToken SceneLoadToken;
public static Transform FindPlayer()
{
//return player through some means
}
}
public class LoadScene : MonoBehaviour
{
public string SceneName;
public SceneTeleportToken TeleportToken;
//this should be called by whatever triggers the loading of the scene
public void DoLoadScene()
{
GameManager.SceneLoadToken = this.TeleportToken;
SceneManager.LoadScene(SceneName);
}
}
public class SceneLoadedSpawnPoint
{
public SceneTeleportToken TeleportToken;
void Start()
{
if(GameManager.SceneLoadToken == this.TeleportToken)
{
GameManager.SceneLoadToken = null; //clear it
var player = GameManager.FindPlayer();
if(player == null) return;
player.position = this.transform.position;
}
}
}
Agreed. ScriptableObject instances are perfect for this sort of “destination” encapsulation. Properly designed, the entire app can “move around” within itself by these things, including all UI button navigation.
Definitely do NOT use enums ever for a list of places, if you intend those enums to be serialized in scenes or prefabs or assets, because enums are bad in Unity3D if you intend them to be serialized:
It is much better to use ScriptableObjects for many enumerative uses. You can even define additional associated data with each one of them, and drag them into other parts of your game (scenes, prefabs, other ScriptableObjects) however you like. Teferences remain rock solid even if you rename them, reorder them, reorganize them, etc. They are always connected via the meta file GUID.