Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

MakePersistent(gameObject);

Discussion in 'Scripting' started by VICTOM, Apr 28, 2007.

  1. VICTOM

    VICTOM

    Joined:
    Aug 28, 2005
    Posts:
    233
    I created a test project called persistentLoader. It works. But yet again I find an oddity - easily explained but not what a developer would expect/want.

    My project has 3 levels index 0-2. Each level has a cube gameObject for visual reference. Lighting changes too. OnMouseDown of the lower left cube will load the next level until there are no more levels and it raps back to level 0 again.

    2 things,
    1) the persistent cube is still in level 0 on the return to level 0 so now there are two persistent cubes. So this debunks my theory that 2 instances of a persistent gameObject causes my problem. It still function.

    2) It still functions as normal except on the 2nd pass through the levels on what would be the 5th click (I think) I have to double click to get to the next level. I'd expect this to be because I was clicking the wrong persistent instance of the cube BUT it worked with multiple cubes 2x before and I won't have this issue again until the next time around in the same spot. Is this a hint to my other problem? or is this so remote ignore it?

    This now brings up the issue how do I destroy the original instance that I told Unity - DontDestroyOnLoad() - but WHY would a developer want a persistent gameObject to multiply itself every time you revisit the level.

    I'd like to suggest MakePersistent(gameObject); this function would do what was expected... take the object with you so that when you returned it wasn't there again. I'm sure there is some way of Destroying a DontDestroyOnLoad object with some code hack but this doesn't jive with the Unity mantra.
     
  2. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    In the Awake() or Start() function of your persistent script you could check if the object is already in the scene with a quick find opp or whatever and Destroy this one if it is already in the scene, but as you said that is not the nicest method.

    I would second a wish-list entry for this if there is no other nicer way to do it that we are both missing. ;-)

    -Jeremy
     
  3. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    394
    To me your MakePersistent(gameObject) is complicated and would be unclear. It is a DontDestroyOnLoad() and if you see a second object of this type on level your loading then destroy it. Or maybe destroy it when loading the same level this object was originally loaded from. I think putting a script with a check in awake or start to destroy or not create the object is more straight forward in most cases. I would not like to see the API expanded for this special case as each API function adds to the complexity of using the API. I think a note in the description mentioning that you get a second object if you reload the level would be good though.

    Cheers,
    Grant
     
  4. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    Ive just had the same problem a couple of days ago. In my experience with other game engines, this is indeed an oddity in Unity.

    If an object is 'not destroyed on load' then IMO it becomes a kind of global game object (as opposed to a scene object) - in this case if we reload the level any 'globalized' objects that already exist should be ignored (this would of course be confusing if you dynamically generate objects at load, but you would ideally consider that in your dynamic coding).

    I dont know if a MakePersistent() function is suitable, but at least there should be a Global and Scene context that can be controlled from any game scene.

    Maybe this should be in the wish list :)

    Cheers
    Shaun
     
  5. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    You can just call Destroy on the game object to kill it manually.
     
  6. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    I also found this kind of strange when I did I Hate Clowns. If you want a "global" object in all of your levels, you need to make sure it exists in each one.

    I second the idea of a global context--somewhere to put objects that will exist in all levels for that project. Actually, my needs would probably be met with a single global object that I could just drop scripts on.
     
  7. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The way i have handled this in past projects, was simply by putting those global objects in the first scene and marking them as dontdestroyonload. The first scene i would never load two times, thus the case of getting duplicates would never appear. You almost always have a splash screen scene anyway, so this is a good place to put them.

    I definately see the point in having something more automatic, essentially the same concet as objects exposed in edit -> project settings
     
  8. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    Im using the splash screen method now - it works ok provided your making a reasonably linear app - which im not. I have 5 sections, some 2D some 3D, but the users jumps back and forth between them whenever they want (kind of like Tabbed browsing in Firefox)

    So to keep the state of each scene and reload it exactly the same each time is a major challenge. I could put everything in 1 level, but I like the idea of being able to control each section of my app in a level.

    Currently I store the 'state' of the level in a global array (created in the splash level) and then reload the other levels each time the user swaps tabs.

    Any ideas on how to make this easier?
     
  9. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    I do this too for some things. The problem is I have to select that first scene before I click play in order to test out a later level. So that becomes: save current level, select first level, click play, go through my title screen and actually play the game, test whatever I wanted to test, click stop, go back to level I was editing. It seems very cumbersome compared to the smooth workflow found elsewhere in the IDE...

    One suggestion was to have a designated "start" level (forum thread). I'd rather have global objects, though, to avoid the extra time going through my load/title game screens.
     
  10. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Having a designated "global" scene would solve a lot of problems.

    First, if there's initialization you always want to take place, regardless of the scene you're editing.

    Second, if there are global "DontDestroyOnLoad" type objects you always want exactly one of.

    It seems like a fairly simple solution.
     
  11. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    394
    I was wrong :oops: I early said I didn't like the idea, but global objects that are loaded and destoryed seperate from scene loading would be nice.

    Cheers,
    Grant
     
  12. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    I agree that this should exsist, but maybe without an additional function. IMO DontDestroyOnLoad should behave that way already.

    -Jeremy