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
0
Question by holistic1 · Aug 08, 2018 at 09:52 AM · gameobjectreferencevalue

Do gameobjects pass reference by default?

Hello, i have a reference and value problem. if i were to have lines of codes like this;

 int a;
 int b=5;
 
 void Start ()
 {
 a=b;
 a=6;
 //what is "b"
 
 }

Value of variable "b" would still be 5. Which as far as i know it means variable "b" passed its value. Now i have lines of code like this;

 GameObject[] patroledPoints;
     
     void Start ()
     {
         patroledPoints = new GameObject[transform.childCount];
         for (int i = 0; i <patroledPoints.Length ;i++ )
         {
             patroledPoints[i] = transform.GetChild(0).gameObject;
             patroledPoints[i].transform.SetParent(transform.parent);
         }
     }

Now when i start the game with these lines, children of the object that this script is attached to simply stops being child of that object. The problem here is i didn't do that operations to the children of that object, i did it to patroledPoints[i]. Which could only mean the children passed as reference to the patroledPoints[i]. So is it safe to assume that gameobjects always pass itself as references, or the situation here is completely something else?(I am kind of new to the reference and value subject so if there are mistakes with my terminology, feel free to correct me.)

Comment
Add comment · Show 1
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 Harinezumi · Aug 08, 2018 at 10:51 AM 0
Share

Yes, GameObject is a so-called reference type and assignment assigns by reference, not value.

In C# all the basic types (e.g. int, char, float, double) and all the types defined by struct (e.g. Vector3, Color, RaycastHit) are value types, that is assigning to them assigns the value. The rest of the types are (e.g. string, GameObject, Transform) are reference type, and assigning to them assigns the reference.

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Aug 08, 2018 at 11:35 AM

"Passed by Value" vs "Passed by Reference"

All variables are passed by value, always. The only exception are out and ref parameters where the variable is passed by reference. People always confuse the concept of a value type or reference type with the concept of passing a variable. Whenever you assign one variable to another you always copy it's content. Where people are confused the most is what "content" actually means.


The content of a value type is just the value itself. So an int variable that contains the value 5 has the content "5" and when you assign it to another variable or pass it as parameter to a method it's value is copied.


The content of a reference type however is not the object which the reference might point to. The content is the reference itself. I know in C# we have managed references but just for the sake of argument you can imagine a reference as a pointer. So the content of a reference type variable is just the address of some memory location where the actual object is located. Now when you assign a reference type variable to another reference type variable you also will copy the content of the variable which is the memory address that is stored in the variable. Of course when you access the object that the reference is pointing to, both variables will point to the same object. However the two variables are not linked in any way.


Think about a reference like an actual address. The white house has the address "1600 Pennsylvania Ave NW, Washington, DC 20500, USA". If you store that in a variable you now have a "reference" to the white house. When you assign this variable to another one the address is copied into the other variable. Changing the address in one of the two variables will not change the address in the other variable. However if you send a rocket to that address which destroys the white house, the referenced object has been "changed". So everybody who uses their reference to the white house will see those changes.


ref and out parameters are actually implemented as pointers onto variables. ref and out only applies to parameters of methods. You can't "store" a pointer to another variable into a variable. At least not in safe managed code. When i said to a variable i mean to the location in memory where the variable content is stored and not the object the reference might be pointing to.



To the actual issue here

edit

So since we basically worked out that our variable content is actually passed by value we will have a look at your code.

GameObjects are objects which live on the heap. Objects are reference types. So a variable of type GameObject actually stores a reference to an actual gameobject somewhere on the heap. The "gameobject" object itself is not stored in the variable. The variable only holds a reference to the actual object. So of course when you store the references to all the child objects in an array and then use those references to manipulate the objects you always manipulate the actual object.


If you actually want a copy of the child gameobjects you have to use Instantiate to create a clone.


Note that your for loop only works because you change the parent of each child object. Otherwise you would always access only the first child of the gameobject. Since you change the parent the object disappears from the child list of our object and therefore the index 0 will now reference the next child

Comment
Add comment · Show 6 · 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 holistic1 · Aug 08, 2018 at 11:57 AM 0
Share

This line of code along with the one below it is supposed get the child out of its parent. And that's what i thought at first, i put "i" there. But notice that each time i get a child out, the "second" child becomes the "first" child. Hence the "0". Code works just as i wanted it to be i don't know why you thought it wouldn't work.

avatar image Harinezumi holistic1 · Aug 08, 2018 at 12:25 PM 0
Share

It's a bit difficult to understand what holistic1 wanted to do with that code, and it does smell, but it makes sense once you notice that patroledPoints[i].transform.SetParent() removes a child of transform, so child 1 becomes child 0 and so on.
A easier to understand way of writing it would be:

 private List<Transform> patroledPoints = new List<Transform>();
 
 private void Start () {
     List<Transform> patroledPoints = new List<Transform>();
     while (transform.childCount > 0) {
         Transform child = transform.GetChild(0);
         child.SetParent(transform.parent); // parent child to its grandparent
         patroledPoints.Add(child);
     }
 
 }
avatar image Bunny83 holistic1 · Aug 08, 2018 at 12:28 PM 0
Share

Ahh I just realised that you use "transform.parent" as new parent. I first thought you just set the same parent as it already was ^^. Of course when you run that code you actually change the parent of all your childs to be a child of the parent of the object you have this script attached to. This is what happens:


Though this has nothing to do with passing variables by reference or value. A GameObject or Transform are objects and therefore reference types. When you pass around references to objects you never will create copies or clones of the objects. Clones has be be created explicitly with Instantiate.


Though we don't know what behaviour you want to achieve or what behaviour you would expect. Anyways I'll edit the end of my answer.

avatar image holistic1 holistic1 · Aug 08, 2018 at 12:52 PM 0
Share

I just read your edit. You are right about "Note that your for loop only works because you change the parent of each child object.". But whole point of that "for" loop is just that. To get the childs out of that parent(If there is any).

avatar image Bunny83 · Aug 08, 2018 at 12:13 PM 0
Share

ps: If you're still not sure about the difference between the type of a variable (value type / reference type) and the concept of passing variables by value / by reference, I've written an even more detailed answer over here

avatar image holistic1 Bunny83 · Aug 08, 2018 at 12:40 PM 0
Share

Yes, i actually read that a few times before posting this question. Very helpful.

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

137 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 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

Reference creator of gameObject 1 Answer

Accessing other GameObjects Script Variables 2 Answers

Vector3 is a primitive type in Unity? 1 Answer

The name `gameObject' does not exist...? Yes i did my research. 1 Answer

Access main camera from different GameObject script 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