Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Best way to dynamically load content?

Discussion in 'Scripting' started by iEchoic, Mar 30, 2014.

  1. iEchoic

    iEchoic

    Joined:
    Dec 27, 2013
    Posts:
    14
    Hi all,

    I want to dynamically create/load all content in my game (via prefabs) instead of using the editor to place content. The method I've been using to do is using Resources.load( path ), and then creating a GameObject using this resource. However, this has a serious downside: it requires me to mirror my entire folder structure in-code, and any time I move, rename, or restructure files, I need to update path(s) in source. This is obviously undesirable.

    I imagine there has to be a better way to dynamically load and manage content - what is it?

    Thanks!
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    At first I expected you to once again try to work against the natural workflow of Unity, which is a data-driven editor, while you look at thing from a code-driven point of view. Micro-managing asset from code is usually wrong, no matter the framework or the paradigm. Even Visual Studio gives you tools such as the Resources container to handle that automatically.

    There's many different way to load and handle asset at runtime... But it means I need to know what is your real intention to give you the right solution.

    What are you exactly trying to do?
     
    lifeisfunxyz likes this.
  3. iEchoic

    iEchoic

    Joined:
    Dec 27, 2013
    Posts:
    14
    :rolleyes:

    There are plenty of modern, successful engines that do exactly this, and thousands of successful games created in this manner. Unless you're misunderstanding my goal - I'm referring to instantiating prefabs in code.

    Yes, and Visual Studio doesn't force you to access resources by file path. Which is the point of this thread.

    Edit: as to what I'm trying to do, I want to dynamically load assets into my level (such as the background, characters, and other objects) without pre-designing them in the editor. They'll all be determined dynamically. The method I'm using to do this is to instantiate prefabs. The issue I'm running into is that this requires me to place path information into my code, and I'm wondering if there is a better approach.
     
    Last edited: Mar 31, 2014
  4. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    iEchoic,
    The answer to your problem could just be:
    http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html

    But this might not work, since you still have potential issues getting the initial reference to the resource. This thread has some discussion about a few ways to go about keeping track of the actual resources:
    http://forum.unity3d.com/threads/198120-Using-Visual-Studio-T4-code-generation-with-Unity

    The most frequently cited method is to drag a reference to the prefab onto the script that spawns stuff. I imagine this is not what you're looking for.

    Edit: If none of that is useful, then the question is: "how would you like to drive the dynamic load?" - or what's going to drive the decision making on what resource to use at what point?

    I did a lot of my model loading by pure convention (assure the model is named matching an items key for instance). Other times I put together a config file to match models to types. In other places I'm generating the meshes procedurally. You can also do some mixture. It all depends on what it is exactly you're trying to accomplish. Do you have an example?
     
    Last edited: Mar 31, 2014
  5. iEchoic

    iEchoic

    Joined:
    Dec 27, 2013
    Posts:
    14
    I am using Instantiate - but it takes a reference for which I need to use Resources.load to find dynamically (as far as I am aware).

    Thanks for the second link - it looks like this guy is trying to solve the same problem I am. This tells me there probably isn't a better editor-supported way to do this, but I like this approach to working around this limitation, and may end up doing the same.
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Is there a reason why you wouldn't have a GameObject holding the currently running code, that could also have an exposed GameObject field?

    If you do;

    Code (csharp):
    1.  
    2. public GameObject prefab;
    3.  
    In a MonoBehaviour, it will expose that field to the Inspector. You can then fill that field with the prefab of your choice. Unity will handle the reference/serialization and you only need to do Instanciate on the prefab variable.

    What I was asking is, is there a architectural needs for you to load manually an object? And if so, what is the intended design?
     
  7. iEchoic

    iEchoic

    Joined:
    Dec 27, 2013
    Posts:
    14
    Maybe this will help you understand why my problems seem so code-centric (I can find little value in using the editor here):

    I'm creating a set of levels, which you can envision as 2d planes with a set of physics objects on it. The stage will be randomly selected from a set of stages, and the content (physics objects on this stage) is going to be procedurally generated - generated dynamically at runtime. The solution I've come up with is to:

    1. Pick a random stage from a list
    2. Load the prefab for this stage
    3. Instantiate the stage
    4. While some condition is true, use some algorithm to pick an object to place on the stage
    5. Load the prefab for that object (Resources.Load)
    6. Instantiate the object on the stage

    Is there some way I could benefit by using the editor in this case? It seems like my only approach for this sort of dynamically-generated content is to add items via code.
     
  8. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    There is ALWAYS benefit in using an editor. Even if you have to build that editor yourself.

    First, I would ask if "loading" by name is needed in this case. Do you have so many level and objects that you would blow up the memory? Could everything be loaded up-front and just be instantiated at runtime? If so, you just need to have List<GameObject> and fill them with your prefabs. It would probably be preferable to do it that way, because Resources.Load tends to hang Unity's main thread.

    Or, each "stage" could be a different "scene", and in each scene, you could have your "level generator" script that would hold a list of prefab that can be instantiated in this specific stage. This way, no "Resources.Load" call, and far less memory used.

    Or if you really really want to keep the Resources.Load, you could make yourself a Editor script that would parse every folder and sub-folder and builds list of asset path in a .asset. That way, all your "hard-coded" string would become data and would be automatically updated at the push of a button.

    I worked on a endless runner type of game, and I made this (http://i.imgur.com/5Vz1oln.png) editor for the designer. They can control completely how the game is generated, in what order and how challenges spawns on the road. And I have no data to handle... ever.
     
    Last edited: Mar 31, 2014
    Friki_Piki likes this.
  9. Fellshadow

    Fellshadow

    Joined:
    Dec 2, 2012
    Posts:
    169
    I was actually having this exact same issue not too long ago. After asking around, lots of googling, etc, etc, I found that there really is only two options:

    1) Have references to the prefabs in the editor. For example, say you are dynamically generating terrain from prefabs. You could have a "TerrainManager" object, that has a List of all the different prefabs of terrain. When you generate the terrain, you could just access the object and that list to determine which prefab to use.

    2) Resources.Load (This is the method I ultimately went with). You already know how to use this, but that being said, you shouldn't need to mirror anything. You'll probably have to mess around with your code for the optimal way.

    But, after reading what you are trying to do, I would suggest option 1. In step 4 "While some condition is true, use some algorithm to pick an object to place on the stage" you should be able to get your prefabs in this step from a list. You obviously have some sort of list of IDs or something that you're picking from to pick an object. Instead of IDs (or however you're doing it) replace that with the prefabs of the objects.
     
  10. iEchoic

    iEchoic

    Joined:
    Dec 27, 2013
    Posts:
    14
    Interesting, #1 sounds like it may be a good solution. Thanks!
     
  11. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    There are cases for other non-visual tools, especially once you start getting into large amounts of things. Once you pass a certain threshold (general purpose) visual editing becomes really cumbersome. You can always build specialized tools for everything, but there's a hell of a lot of value in plain text.

    Being able to find things with regex's, being able to diff files, having a clear revision history from version control, being able to dump stats into excel for quick number crunching. The advantage to plaintext is that you already have an incredibly rich set of tools to work with. You could integrate them into some kind of visual editor, sure, but having access to these tools 'for free' can be valuable!