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
4
Question by initTechsuport · Dec 29, 2016 at 11:42 AM · variablefunctionchangeinstancemethod

Passing Parameters by Value or by Reference

Passing something to a function that changes a variable/object outside the function, vs passing things to the function that are lost upon completion of function.

I know classes have this ability, while basic variable types are instanced in the function.

For example

 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 RaycastHit hit;//    <----    modifying this variable
 if (Physics.Raycast(ray, out hit, 100))//  <-   by putting it in this function
             Debug.DrawLine(ray.origin,    hit.point);
 DoStuff(hit.thingsSetDuringFunction);






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
38
Best Answer

Answer by Bunny83 · Dec 30, 2016 at 01:13 AM

Well, a lot people seem to confuse the concept of value / reference types with the concept of passing parameters to methods. It's a general misconception that reference types are passed by reference. By default all parameters are passed by value.

Let's start by defining what a parameter is. A parameter is just a local variable that only exists within the scope of the method. Those variables are "initialized" when you call a method by the values that are passed in.

The biggest confusion seems to come from passing a reference type variable by value. What is the "value" of a reference type variable? It's simply the reference to an object. Of course a method can use a reference that was copied (passed by value) into the local parameter variable to directly access / modify the object behind the reference, but the variable that was passed in can not be modified.

So there are basically two variable type families (value types and reference types). And there's also two different ways to pass a variable to a method (passed by value and passed by reference). Note that this only applies when passing variables to a method. Literal values are always passed by value.

the default: pass by value

Consider the following methods:

 void f(int x) { }
 int g(GameObject obj) { return 5; }

By calling f(5); we actually copy the integer value of 5 into the local variable "x" of the method "f". The same concept holds true for reference types.
If we call g( new GameObject("test") ); we create a new gameobject and copy the reference to that object into the local variable "obj". In both cases we have copied the value that was passed to the method into it's local parameter variable.

Passing variables to such methods has the same effect.

 public GameObject myObj;
 public int myInt = 7;

By calling f(myInt); we copy the value of the variable "myInt" into the variable "x" and if we call g(myObj); we copy the reference which is stored in the variable myObj into the variable "obj". The method can not modify the passed variable. It can use and re-assign it's local variable but it won't affect the content of the variable that was "passed in". Keep in mind that the "content" of reference type variables is the reference, not the object behind the reference.

pass by reference (out, ref)

It's possible to declare a parameter of a method as reference parameter by using the "ref" or "out" keyword. They both serve the same purpose but "out" has some additional properties which i will explain below.

Consider those methods:

 void h(ref int y)
 {
     Debug.Log("current value of y: " + y);
     y = 42;
 }
 
 void k(ref GameObject obj)
 {
     obj = new GameObject("test");
 }

When you call those methods you have to use the "ref" keyword and you have to use an actual variable. It's not possible to pass in a value, only variables. The "ref" is about the variable and not it's content. So when calling h(ref myInt); you don't copy the content of myInt into the local variable. Instead the local variable becomes an alias for the passed in variable. So you basically pass a pointer to the memory location where the passed variable is stored. So when using that alias you actually using the original variable. That means you can read and write the content of the original variable. After calling "h" with myInt as ref-parameter myInt will contain "42".

The same happens when you call k(myObj);. The method actually replaces the content of myObj with a newly created GameObject. Again, keep in mind that the content of a reference type variable is "the reference".

The "out" keyword

Like i said above out does the same as ref but has some additional constraints for both, the caller and the method:

  • A method with an out parameter has to ensure to initialize the variable with some value.

  • The method can not read the out parameter before it has got assigned inside the method. It's treated as uninitialized variable.

  • The caller can rely on the above fact that a method has to assign a value to the passed variable. Therefore passing an uninitialized variable to an out-parameter is considered an initialization of the variable.

So out parameters are just a special version of a ref parameter. It's generally used when you just need to return something but don't need to pass in a "current" value. A common example in Unity is the RaycastHit parameter of the Physics.Raycast method. Another general example is the TryParse method of most primitive datatypes.

Additional restrictions for ref-parameters

ref-parameters are like a special kind of variable type that doesn't exist as normal variable type. So it's not possible to "store" or return such a variable reference. ref-parameters can be passed further down to other methods with ref parameters but never "upwards" as this would allow to return a reference to a local variable of a method that is out of scope and extent.

ref-parameters can not be used for coroutines. Coroutines are implemented with auto generated statemachines. Statemachines have to store the current state in class variables. Since ref-parameters can't be stored in class variables they aren't supported for coroutines. This is not a limitation of Unity but a limitation of the ref-parameter itself. Trying to declare a parameter of a coroutine as ref or out parameter will cause a compile error.

Finally i want to note that ref and out parameters aren't something Unity specific. They are features of C# / .Net and all those limitations come with them and aren't Unity specific. If you need further information on that topic or if you have trouble understanding what i just said, you might want to refer to some general C# / .NET resource like StackOverflow.

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 tanoshimi · Dec 30, 2016 at 09:31 AM 2
Share

A very thorough answer. I'd only add that out parameters are useful when you want to return multiple values from a function.... otherwise you simply return a single result.

avatar image changemaker · Jul 01, 2020 at 10:52 AM 0
Share

I am writing because i want to be sure about a thing that you said:

"The method can not modify the passed variable. It can use and re-assign it's local variable but it won't affect the content of the variable that was "passed in". Keep in $$anonymous$$d that the "content" of reference type variables is the reference, not the object behind the reference."

Please correct me if i am wrong.What you tried to say is content" of reference type variables are not directly affected but local variable has the same adress with the copy of the reference type and we know that if we change something via that local variable ,we also change all the variables(includes copy too) that contain that memory adress as well, so content of the variables are indirectly affected by that method's local variable

avatar image
5

Answer by tanoshimi · Dec 29, 2016 at 11:46 AM

It sounds like you're talking about:

  • passing parameters by value (i.e. when a function receives and modifies a copy of a variable, which is the default for structs and simple types like int, float etc.)

vs

  • passing parameters by reference (when a function receives a reference to the variable itself and modifies the original, which is the default for classes).

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 initTechsuport · Dec 29, 2016 at 08:59 PM 0
Share

If that is the extent of the formal ter$$anonymous$$ology then I'll mark the question answered, but i would thoroughly appreciate any tangential info, or sources/example for exact use, and variation of use (i.e. how can i pass a simple type by reference, or entire classes "by value" if i want something to manipulate but to keep the original)

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

63 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

Related Questions

The variables and functions 2 Answers

How do you achieve variables and functions that are global between scenes? What is the BEST way? 1 Answer

Can I use 'variable name & function name' in a foreign language? (유니티는 '한글 변수명 & 한글 함수명' 이름 지정이 가능한가요?) 3 Answers

Variables not changing correctly 2 Answers

How to: make changes to a var over real time units instead of frame units? Mathf.Lerp 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