Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 shanusmagnus · Feb 01, 2013 at 08:30 PM · c#instantiateclassinheritance

Behind the scenes voodoo w/ Instantiate

I'm trying to wrap my head around the relationship between Unity objects and C# classes and types. To illustrate, I have a prefab called PuckPrefab. It has two C# scripts attached as components: FallScriptCS and OtherPropsCS. I also have a manager object called LogistixMgr, that has a single script component called LogistixScript. So the setup looks like this:

 PuckPrefab
     FallScriptCS
     OtherPropsCS
 
 LogistixMgr
     LogistixScript

Here's the subtle and confusing part. LogistixScript has a member variable:

 public class LogistixScript : MonoBehaviour {
     public FallScriptCS _puckPrefab;

In the Unity editor pane, I drag the PuckPrefab object onto the __puckPrefab_ field. This seems explicable, in a way: a puckPrefab has a component that is a FallScriptCS; if we think of "having a component" as kinda-sorta like "being a superclass of" then it makes sense why Unity would allow me to map a PuckPrefab object to a variable of type FallScriptCS.

Later, however, I have this bit of code (also in LogistixScript):

 FallScriptCS newPuck = Instantiate(_puckPrefab, pos, rot) as FallScriptCS;

What this seems to do is to instantiate an actual PuckPrefab object complete with its FallScriptCS component (as opposed to instantiating just a FallScriptCS object by itself). This is actually what I want it to do, but that's not the point. The point is: how is the compiler figuring out how to do all of this behind my back? The type that is being instantiated is declares as FallScriptCS; the compiler seems to be saying: "Well, you can't actually instantiate a script; but the thing to which this particular script is attached happens to be a GameObject, and I'll instantiate that instead."

The implication seems to be that if I make a generic container, like:

 Dictionary<string, FallScriptCS> pDict = new Dictionary<string, FallScriptCS>();

... and then populate it with the instantiated item:

 pDict.add(newPuck)

then what's getting added is actually a GameObject?

So I guess I'm asking is what is the relationship between a GameObject (like PuckPrefab) having components, and those components being treated (sort of) like descendants in a type hierarchy? What are the rules for type checking and object identity that makes this work?

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

2 Replies

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

Answer by whydoidoit · Feb 01, 2013 at 08:37 PM

Ok so don't think inheritance think composition. It's really something you could do yourself, but it kind of messes you up when you first get started.

GameObject is an class that contains a list of components, an array of them if you like.

You attach instances of these objects to the GameObject which it stores in the array and then it calls special functions on them when the framework dictates. Because they all have references to common things like Transform for positioning they appear to be one object, but they are not. They are just children in an array that are provided the privilege of changing things about where their container is etc. GetComponent is just a call to search through that array and return an object of the right type if it exists or null if it does not.

So what the editor does when you drag on that game object is it calls GetComponent on it and sees if it has the right type for the variable. If it does it stores that component.

Now Transform, your scripts etc etc all inherit from Component - which of course has a reference to its container - GameObject.

So when you call Instantiate it sees its a Component derivative, creates the associated GameObject and all of its Components in its array (deep copies it effectively) then returns the Component type that was used to find the GameObject reference.

Comment
Add comment · Show 7 · 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 whydoidoit · Feb 01, 2013 at 08:41 PM 0
Share

The property transform just does this:

  • Go to the game object list of components

  • Search it for one that is Transform

  • return that

That's why you should cache it. It's not really a stored value, it's a search.

BTW a quick way to cache it if you haven't already

 public class SomeScript : $$anonymous$$onoBehaviour
 {
      public new Transform transform;
 
      void Awake()
      {
           transform = base.transform;
      }
 
 }

After that your transform is cached, but the rest of your code does not need to change.

avatar image shanusmagnus · Feb 01, 2013 at 08:41 PM 0
Share

What a great answer, just exactly what I was hoping for. Thanks!

avatar image whydoidoit · Feb 01, 2013 at 08:47 PM 0
Share

No problem - BTW it's one of those other weird techniques - but you can change things in the prefab before Instantiate and it will instantiate with those values before Awake.

 prefab.GetComponent< $$anonymous$$yScript>().someVariable = someValue;
 
 var newThing = Instantiate(prefab) as Whatever;
avatar image shanusmagnus · Feb 01, 2013 at 09:15 PM 0
Share

btw, is it confirmed that GetComponent does its search w/ a loop? One might imagine that a GameObject indexes its components in a hash table, which would make returning the component O(1). I checked the dox, but there's no mention of it.

avatar image whydoidoit · Feb 01, 2013 at 10:39 PM 0
Share

They're pretty smart about this stuff, so it's probably o(1) but bear in $$anonymous$$d that a Send$$anonymous$$essage is 150x slower than a delegate or event.

Show more comments
avatar image
1

Answer by Jessy · Feb 01, 2013 at 08:38 PM

If a game object, component or script instance is passed, Instantiate will clone the entire game object hierarchy, with all children cloned as well. All game objects are activated.

If the object is a Component or a GameObject then entire game object including all components will be cloned.

That's what UnityEngine.Instantiate does. It's not just a constructor + deserializer or something. You don't use constructors on components; they don't exist independently of game objects.

http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html

Comment
Add comment · Show 1 · 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 shanusmagnus · Feb 01, 2013 at 08:53 PM 0
Share

Thanks. Believe it or not, I started on the Instantiate page, but apparently was blinded by my own preconceptions of Instantiation == construction and so didn't absorb it. Appreciate the pointer.

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

11 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

Related Questions

An OS design issue: File types associated with their appropriate programs 1 Answer

Multiple Cars not working 1 Answer

C# Utility Class 1 Answer

Parent Class variables in Child Class's Inspector (C#) 0 Answers

C# Extending Script causes InvalidCastException on 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