Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by ausLancaster · Jan 19, 2018 at 04:44 AM · instantiateprefabsmonobehaviour

Instantiating a prefab at runtime (without using Monobehaviour or Resources folder)

I would like to instantiate a prefab using a script that does not inherit from Monobehaviour. The way I have been doing it is this:

 GameObject unitPrefab = (GameObject)Resources.Load("Unit", typeof(GameObject));
 GameObject.Instantiate(unitPrefab);

where "Unit" is a prefab in the Resources folder.

Recently however, I have read that loading resources in this way is bad practice. Is there another way I can instantiate the prefab? Or is it wrongheaded for me to create classes that do not inherit from Monobehaviour? (I want to be able to create objects using "new", pass parameters etc).

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Lysander · Jan 19, 2018 at 06:17 AM

At least 90% of the scripts in Unity projects are NOT MonoBehaviours, or derived from UnityEngine.Object. I also don't see why it would be bad practice to use Resources.

Unity asset types MUST be either referenced by a scene object. stored in Resources, or loaded from an asset bundle in order to be usable in the build (with minor exceptions like PNGs, and barring significant effort). If you don't want to use Resources, then your only easy option is to make a GameObject in a scene, have a public GameObject variable on a MonoBehaviour attached to that GameObject, and drag-and-drop the prefab into that reference.

Some people choose to do this by creating a kind of "initialization scene" where they handle loading assets and making them available to the rest of the game's objects. You can manage this with a singleton GameObject (use DontDestroyOnLoad on it so it persists through scene changes), or by simply passing along the references to a static handler. You'll still have to make GameObjects and attach those prefab references to MonoBehaviours attached to them, but it gets it all done in one place so that you don't need to worry about doing it for individual scenes.

There's nothing at all wrong with Resources as long as you don't get lazy though- load everything you need at the beginning of the scene, try to avoid instantiating or destroying objects (use object pools- use the HELL out of object pools), and always start off big dynamic events by pre-loading temporary stuff and then dump it all immediately after the event is over- this is the reason for those brief pauses before cutscenes in most console games. Don't think that just because a file is in Resources that you can load it whenever you like, and don't put anything in Resources that you may not want included in the build (all assets there are included, whether they're used or not) and there's zero reason not to use it.

As a final note, I would like to make you aware of the RuntimeInitializeOnLoad attribute. Toss that onto a static method, and that method will run when the game starts (either before anything in the scene is created, or after Awake has been called on everything in the starting scene). This allows you to cut out the need for "initialization scene" MonoBehaviours, since you can just immediately load whatever you like from Resources into a static handler, without any middle-men in the scene to hand them over. It also means that, if you have a singleton MonoBehaviour set up for it, you can actually hook into Unity's Update/LateUpdate loops without being a scene object or deriving from MonoBehaviour. Just create events on your "UpdateHook" singleton, allowing anything to sign up to them, and invoke them in Update so everything that's listening gets updated as well. This can be tremendously useful.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ausLancaster · Jan 19, 2018 at 11:58 PM 0
Share

Thanks for the answer. A follow-up question: I'm trying to work out how to structure my code in a good way. I have a Squad class that contains an array of unit objects. These units need to be represented in the scene however, so I have them create a unit prefab at initialisation saved as a variable in the unit class, which is moved when the unit is moved. Is this a typical thing to do?

Then I would like to be able to select units. So I will need a new script that uses $$anonymous$$onobehaviour (for On$$anonymous$$ouseEnter()) attached to the unit prefab. But where should the logic for selecting and moving units go? In the squad class? Unit class? A new script on the Unit prefab?

Additionally, do you have any tips/resources on how I can learn to structure my code well in Unity generally?

avatar image Lysander ausLancaster · Jan 20, 2018 at 09:59 AM 0
Share

Disclaimer: this is all my own personal beliefs and style, and should not be taken as gospel.

I like the idea of separating the data from the visual representation of that data, but I prefer it when there's a well-defined dependency chain. The avatars as they exist in the scenes (GameObject entities) should know about the data objects they represent, but the data objects shouldn't know about the avatars. UI is the same way- nothing should have direct knowledge of any UI elements that isn't itself a part of the UI system, but the UI needs to know what data it's representing so it knows how to display it properly.

With that in $$anonymous$$d, I wouldn't have the characters' data objects instantiate their own avatars into the scene. I wouldn't even have them hold their own prefabs- I would use a static handler that's in charge specifically of all of the in-game avatars for the project, and whatever manager in the scene decides "I need CharacterX here" should ask that handler "Give me the avatar for CharacterX", and it should comply. This is especially important later on when you're working with AssetBundles.

I'm having a bit of trouble visualizing your situation (it's extremely late at the moment), so I'll just give some general advice. $$anonymous$$ost important I$$anonymous$$O: objects should handle themselves. The big point that you'll often see made in program$$anonymous$$g about "never make fields publicly accessible, only properties and methods" really boils down to "never change another object's fields". When ObjectA changes a field for ObjectB, ObjectB has no possible way to know that that change has occurred and react to it, unless it's (ridiculously) constantly monitoring the value. By using properties, you allow for the possibility that ObjectB will be able to tell the value is being retrieved, or set, and react appropriately.

This mentality should, I$$anonymous$$O, be extended to every aspect of your development. An object should be in charge of its own data- if the data needs to be changed, it should be the one to do it. Responsibility for any action should be given to the object most intimately associated with it (least common deno$$anonymous$$ator kind of thing). If you want to perform an action on the squad as a whole, the squad object should process that action, but then relay commands down to its members- the members should then respond appropriately to that command.

If you're worried about where to put the controls for the squad, you need to ask yourself "is the squad controlling itself?". No, it's not, you're controlling it (think of yourself like the Game $$anonymous$$aster). You should probably handle that from a Game$$anonymous$$anager style object ins$$anonymous$$d- if an input command relates to the squad, then pass it to the squad, but if it relates to UI or something else, then pass it there ins$$anonymous$$d.

Out of space for the comment, and exhausted, so I'll stop here for now. Let me know if you need any additional assistance.

avatar image ausLancaster Lysander · Jan 26, 2018 at 12:17 PM 0
Share

Thanks this is super helpful.

If I have a static handler for getting prefabs, are they are stored in that class?

Also, if I create a new Unit data object I will want a prefab created at the same time. $$anonymous$$y first instinct would be to make a call in the constructor to a method in the static handler like "CreateUnitPrefab". But should the models know about the handler?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

94 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Instantiate Reference Problem 1 Answer

Fireball instantiate - lags 1 Answer

Instantiating Prefabs Lags in Android 0 Answers

Prefabs wont instantiate using a for loop? 1 Answer

Threads for Instantiate 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges