Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
0
Question by NPS · Feb 10, 2014 at 10:27 AM · monobehaviourinitializationexpose

Assign exposed vars before instantianting prefab?

I have a prefab (a few GameObjects with my scripts). Some of these scripts have exposed variables. In their Start() method I'm initialising some other variables based on the exposed ones. The problem is - when I try to instantiate such a prefab the Start() method gets called before I get a chance to assign the exposed variables.

What should I do?

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

3 Replies

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

Answer by whydoidoit · Feb 10, 2014 at 01:00 PM

You can set variables in the script on the prefab before you instantiate it. Then the variables will be set correctly in Awake and Start.

Comment
Add comment · Show 13 · 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 NPS · Feb 10, 2014 at 01:28 PM 0
Share

For some reason I can assign some variables but can't assign others. (For instance my prefab has $$anonymous$$egaShapeFollow.cs from $$anonymous$$egaShapes plugin and $$anonymous$$yScript.cs. Both scripts have a variable of the same type ($$anonymous$$egaShape) but I can assign only the variable in $$anonymous$$egaShapeFollow.cs and not in $$anonymous$$yScript.cs. :/ )

avatar image whydoidoit · Feb 10, 2014 at 01:30 PM 0
Share

I guess that one of those $$anonymous$$egaShapes things might doing its stuff in Awake or Start itself. But you could post some code, perhaps it's something else not ready yet?

I do assign paths for $$anonymous$$egaShapes pathfollowing in my code, but I'm sure the use case is different.

avatar image NPS · Feb 10, 2014 at 01:32 PM 0
Share

By "can't" I meant Unity Editor doesn't allow me to "drop" an object on the variable field (like when the types don't match and the option is disabled). $$anonymous$$yScript has just a public $$anonymous$$egaShape variable so I'm not sure what code I could post.

avatar image whydoidoit · Feb 10, 2014 at 01:34 PM 0
Share

Oh hang on - you mean you are looking at the project view of your script and wanting to assign default parameters to exposed variables. Right it's making a bit more sense now. Ugh - I just wish that functionality wasn't there, it's very flaky. If you AddComponent that script it just ignores all those values for instance.

avatar image whydoidoit · Feb 10, 2014 at 01:35 PM 0
Share

$$anonymous$$ost likely you are trying to allocate an item from the scene to the script - that is never possible as the script doesn't know which scene it will be instantiated in.

Show more comments
avatar image
6

Answer by yatagarasu · Feb 10, 2014 at 03:03 PM

You can call SetActive(false) on prefab before instantiating it, then instantiate an object and set your vars, and then class SetActive(true) on instantiated object and prefab. Start and Awake are called only on active objects.

Comment
Add comment · Show 2 · 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 NPS · Feb 10, 2014 at 04:18 PM 0
Share

I wish I could mark 2 answers as correct as this one also solves my problem. +1 though. ;)

avatar image monotoan · Feb 06, 2018 at 05:37 PM 0
Share

I like this answer in combination with @wibble82 's. Essentially what you're looking for here is a Unity-compatible version of a class constructor function where you'd just pass your initialization values into the constructor as parameters, e.g.:

 //Note: these won't work
 $$anonymous$$yGameObject newObject = new $$anonymous$$yGameObject(initValue1, initValue2);
     //or
     newObject.AddComponent(new $$anonymous$$yComponent(initValue1, initValue2));

Unfortunately, as I understand it, $$anonymous$$onobehavior-derived classes prohibit this approach in favor of initialization through the Awake(), Start(), and OnEnable() functions. This works well in most cases, but doesn't do so well when you're trying to instantiate a new GameObject with components that need initial values set from an external source at that moment, and need those values right away to start working properly. So making sure that GameObject is set Inactive -- or that component is un-enabled! -- in your prefab, until you can call an init function to pass in starting values, seems like a good solution.

 //Set GameObject or Component to inactive / disabled in prefab first
 $$anonymous$$yGameObject newObject = Instantiate<GameObject>($$anonymous$$yGameObject);
 newObject.GetComponent<$$anonymous$$yComponent>().Init(initValue1,initValue2);
 newObject.SetActive(true);
 //or 
 newObject.GetComponent<$$anonymous$$yComponent>().enabled = true;

There is also an interesting discussion here about how you can get something like constructors in $$anonymous$$onobehavior components:

https://answers.unity.com/questions/445444/add-component-in-one-line-with-parameters.html

avatar image
1

Answer by wibble82 · Feb 10, 2014 at 11:37 AM

So my understanding (just to clarify) is that you have a prefab, which contains some scripts. Those scripts have a load of members that control how the script operates, so you want effectively want to be able to go:

  • create object

  • set the members (lets call them initialisation members)

  • have it 'start' and let the script do its thing!

In the simplest case, if you know what the initialisation values are at edit time you would just set these properties in the editor, however you've probably hit the scenario where the initialisation members are dependent on run time data? In this case what you'll need to do is remove the functionality from the start function (so it does very little), then create a new function (lets call it Init) that you call manually which does the bulk of the work. So the order would be:

  • create the object

  • (its start function is automatically called, but does very little)

  • set the members on the script

  • call 'Init' on the script

That sound ok?

You can make it a little more robust by having the script raise an error when updating if it hasn't been initialised, adding the custom parameters as arguments to the init function and even creating your own special static helper functions that internally do the above code. So you might have:

     public static GameObject CreatePlayer(float player_fatness)
     {
         GameObject obj = Instantiate(player_prefab); //the player is created and start is called

         PlayerScript player = obj.GetComponent<PlayerScript>();
         player.fatness = player_fatness;
         player.Init();

         return obj;
     }

or if you passed the parameters into the init function:

     public static GameObject CreatePlayer(float player_fatness)
     {
         GameObject obj = Instantiate(player_prefab); //the player is created and start is called
         obj.GetComponent<PlayerScript>().Init(player_fatness);
         return obj;
     }
Comment
Add comment · Show 2 · 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 NPS · Feb 10, 2014 at 12:11 PM 1
Share

Thx for answering! I know I can move the init stuff from Start() to $$anonymous$$yInitFunction() and call it manually. But my question was - is it possible to assign the exposed variables before the Start() is called. I guess it isn't? Also - if I "know what the initialisation values are at edit time" how do I set them in prefab? I mean - how do I assign exposed variables of a prefab?

avatar image wibble82 · Feb 10, 2014 at 02:58 PM 0
Share

If you make a member of a mono behaviour public, it should appear as an editable property in the editor. I often have 1 script that represents say 'enemy behaviour', with a load of properties that control it. Then I create a prefab for each type of enemy.

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

22 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

Related Questions

Monobehaviour resets variables after the initialization cycle 0 Answers

bool field initialization ignored 0 Answers

Initialising List array for use in a custom Editor 1 Answer

When do components of loaded prefabs get initialized? 1 Answer

Order of GameObject.FindGameObjectsWithTag(string tag) 3 Answers


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