Search Unity

Removing Duplicates on Load Scene

Discussion in 'Scripting' started by Nitrox32, Aug 22, 2020.

  1. Nitrox32

    Nitrox32

    Joined:
    May 9, 2017
    Posts:
    161
    I'm currently working on a scene manager that will load a new scene and place the player at a spawn point. Currently it works by having a start screen and a portal that will go to a new scene while retaining the player defined in the start screen. It works but this is very inconvenient when level testing because I have to always go to the start screen then to the level. I would like to have a player in each scene for level testing and if I want to begin from the start scene all of the players in the level scenes would be destroyed when the player from the start screen is moved over to the level scene avoiding duplicates.
     
    MoonJellyGames likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    Why not remove the player from ALL your scenes, put him in his own separate scene, then load scenes additively?

    That way you don't even need a Player prefab at all, just have a Player scene and load him additively.

    I tend to break up all my games into partial scenes, all additively loaded by the game manager:

    - UI
    - player
    - enemy manager
    - other stuff?

    and then finally I load the content scene.

    The first batch of screens all have scripts that do nothing until the content scene appears and they know where to spawn the player. In the case of the player he actually turns off his visual components in Awake() and waits for the spawnpoint to appear that is in the content level. I usually just use a MonoBehavior that has nothing else in it for GameObject markers like that, something like "PlayerSpawnLocation".

    This also lets you drop a tiny manager script into the content scene so when you're working on it solo and fire it up, if there is no player scene present it will load it automagically for you.

    The only tricky thing about additive scenes is that they do not load until the next frame. I usually have the game manager yield one frame, then load the content to avoid trouble.

    I often have other transient scenes that load additively for things like:

    - pause UI
    - inventory UI
    - other?

    Once you start using additive scenes you'll kinda wonder how you made it this far without it. It's SO much simpler.
     
  3. Nitrox32

    Nitrox32

    Joined:
    May 9, 2017
    Posts:
    161
    I like the idea, but I'm still in the early stages of learning how to program. I could probably figure it out if I could see some code examples and where they would be placed in the context of these scenes as well as the objects they should be placed on. Could you provide some examples?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    I actually can! I used this technique in my silly little hovering game demo package, located here:

    https://github.com/kurtdekker/hovering

    It's kind of a halfway done mess I haven't touched in a few years, but the second mode (Hovercraft) certainly does this find-my-spawnpoint trick.

    - Launch Mainmenu scene

    - Start the second mode

    - Press PAUSE in the editor.

    Now you can dig through the loaded scenes and see what's going on.

    Unfortunately the script that does the teleport to start actually Destroys() itself after completing its work, which hides how it worked... sorry. Here's that script, and it is on the Hovercraft object:

    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TeleportToNamedGameObject : MonoBehaviour
    6. {
    7.     public string GameObjectNameToSearchFor = "<none>";      
    8.  
    9.     void Update ()
    10.     {
    11.         GameObject go = GameObject.Find(GameObjectNameToSearchFor);
    12.  
    13.         if (go)
    14.         {
    15.             transform.position = go.transform.position;
    16.             transform.rotation = go.transform.rotation;
    17.            
    18.             Destroy(this);
    19.         }
    20.     }
    21. }
    Have fun, take whatever you want, maybe someday I'll push an updated version out.

    The additive scene loader is in wrapper called SceneHelper.cs, but no reason you can't just use Unity's scene manager directly... up to you. Just remember when you load a scene, NONE of it is there until the next frame.
     
    stalyan77 likes this.