Save object between scenes using DontDestroyOnLoad Unity C# - c#

I'm making a 2D game where my character can go in and back out from different rooms, so since every room is a different scene I need to be able to somehow keep my character throughout every single scene, for that purpose unity offers DontDestroyOnLoad()
So I did use that function whenever I'm switching my scenes, however there is a problem with that.
Let's assume that my rooms are only 2 and they are really simple looking like this
Here in this scheme the main room is the one that you start your game in, it contains already spawned prefab of the character. Once we go to the second room my character is being saved with all his good stuff, however if we go back to the main scene/room we can now see 2 characters. Why ? Because our initial character is not being destroyed when different scene are loaded and we also have one that is being created along with the Main room/scene. Now this is really nasty and I don't know how to fix that, I also have the same problem with some scripts that I need throughout every single scene. Any help is appreciated.

You can make the character spawn in the main scene through script - instantiate it. Make sure you give the character prefab a certain tag ("Player" for example).
Then instantiate the character inside an if statement. Using FindGameObjectWithTag(<Tag>) == null you can find out if the character was already created.
public GameObject player;
if(GameObject.FindGameObjectWithTag("Player") == null){
player = Instantiate(prefab,position,rotation) as GameObject;
}

The normal solution is you don't create objects that are set to DontDestroyOnLoad in scenes that can be viewed more than once.
What most people do is create a pre-load scene that is the very first scene that loads with the game that creates all objects that survive between scenes, then that pre-load scene loads the "Main game scene".
If you don't want a pre-load scene then your game object needs to check on on Awake if another instance of the game object already exists. If it does find a instance then it needs to destroy itself. The first instance won't find any other instances so it won't be destroyed but all future instances will be.

Related

Assigning player prefab based on playerIndex at runtime using Unity input system

I want to have some prefabs already in the scene and then assign the players each one to control. The Input Manager is pretty clear for assigning prefabs when a player joins, but can this be changed later?
I know I can have a parent game object with several inactive prefabs as children and activate as needed, but this won't work with my current situation. Really need to just switch altogether if possible.
I'd like to use the "join manually" option which requires me to drag prefabs into the scene in the editor, then how do I assign players to them once the scene starts?
Something like:
if (GetComponent<PlayerInput>().playerIndex == 0)
{
"the player becomes prefab 1"
}
if (GetComponent<PlayerInput>().playerIndex == 1)
{
"the player becomes prefab 2"
}
I'm not sure how to access this by code (I'm pretty new) The input manager script appears uneditable, but before I realized this I tried adding some additional public game objects.
If i understand correctly your intend is to keep the players on scene while changing who controls them, right?
You should be able to get the player disconnected an reconnected to a new index without deleting the Player object from scene. Make shure you use methods properly using the docs: Player Input Manager Docs.
Otherwise I think you need an extra layer or some twist. Maybe keep the players on their indexes but change whos controlling the Player GameObjects?
By the way you can instantiate Prefabs by code using Instantiate()
You can also use inheritance to extend PlayerInputManager and maybe add some SwitchPlayer() function if really needed.
public class CustomPIM : PlayerInputManager {}
The custom class will inherit all methods from PlayerInputManager plus whatever you add.

Is there a way to set a scene's content to a variable?

I have a game where I need to save a scene. I'm doing this by setting the scene to a variable which I can access later. The player then goes to a main menu when they are done.
The player now wants to go back to that scene, however, when it loads normally, it resets to its original state. Is there any way to use this variable to set the scene's contents to the variable I made earlier?
This is how I made the variable: Builder1 = SceneManager.GetActiveScene();
Any help would be greatly appreciated (and yes, I do realize that the variable I made probably doesn't store the scene the way I want it to). Thanks!
Scene is just a reference to the Scene object, and not all of the GameObject's locations/information at that moment in time. If the information in a scene shouldn't be lost yet, then it is advisable to not close the scene yet. Instead, take a look at Additive Scene Loading. You can addivitely load your new scene, switch your main camera to the new scene's camera, and when you are done there you can close the added scene and return the camera to the original scene.
If you're looking to persist data between game loads, then you'll need to consider serializing all of the relevant data in your scene and build a data class to house all of it.

In Unity, when I load a scene a second time, some objects don't show up

I have two scenes: Menu and Game. I'm using C#.
When you die in the game, you get sent back to the menu with
SceneManager.LoadScene("Menu");
There's a script with a GUIButton in the menu that, when clicked, loads the game with
SceneManager.LoadScene("Game");
What I want to happen is that when I click the button in the menu scene, it loads the game as if I just clicked the play button with the game scene open in the editor.
What instead happens is that it goes to the game scene, but some objects from the game scene appear to be missing. I'm not using DontDestroyOnLoad() anywhere.
Some objects from the scene do appear, but others don't. The weirdest thing is that there are some data fields on a script on the missing object that are referred to by some other scripts, and those give values that make sense.
Does anyone have any idea what's going on, or what I can do to get the desired result?
Turns out that the problem was that I was destroying one of my objects if it was not the first time that object was created, and I didn't realize it.
are those static objects or dynamic? try to instantiate them in function which gets called on scene loaded.

Click to move should i verify by tag or by game object?

Recently i came across developing a RPG game as diablo and basically the movement control needs to be carefuly made and verify every element we click before move. I was wondering by having alot of prefab of enemy gameobject, the UI and myself if i must verify by the elements with the tag i want or by the gameobject.
Well for example if i have all UI gameobjects with tag UI and enemys with tag enemy, is it good to verify by tag instead of verying directly by the gameobject name? I'm quite confused with i should use.
This depends on how many GameObjects you are verifying and how often you do it. If you don't this every frame or very often then don't worry about it. If you do it every frame or very often then check the GameObject by tag instead of by name but make sure to use the GameObject.CompareTag function to do so not with the GameObject.tag variable.
The reason is because GameObject.name and GameObject.tag allocates memory. GameObject.CompareTag does not.

How do I create an object that already exists in the Hierarchy in Unity C#

I have a character that when it touches another object(lava), it is destroyed.
Upon death, there will be a GUI that creates a respawn button, but how do I re-create the player object? I destroyed the object with Destroy(collision.gameObject);
The way I would approach your problem would not be to destroy the player when it touches the lava, but rather deactivate the object. Then, when the user clicks the respawn button you would simply activate the object again (but make sure to take him out of the lava first).
This might help for the code-side of things.
Instantiate should do the trick.

Categories

Resources