Search Unity

transform.localEulerAngles.x = 10; does not work in C#

Discussion in 'Scripting' started by techmage, Oct 16, 2010.

  1. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I've decided to switch to C# and am going to be asking some retarded newb questions if you don't mind

    transform.localEulerAngles.x = 10;

    that line ^^

    gives me this:

    Assets/Interdimensional Jesus Velociraptor/scripts/playerControl.cs(15,27): error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.localEulerAngles'. Consider storing the value in a temporary variable

    what?
     
  2. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Unfortunately this is a minor inconvenience that just has to be worked around. 'localEulerAngles' and other accessors like it are implemented as properties (presumably). Since Vector3 is a struct, a copy is returned by the property (not a reference to the field), so when you try to assign a value to the 'x' field, you're actually trying to modify the temporary copy that was returned.

    The workaround, more or less, is to write something like this:

    Code (csharp):
    1. transform.localEulerAngles = new Vector3(
    2.     10f,
    3.     transform.localEulerAngles.y,
    4.     transform.localEulerAngles.z
    5. );
    If this is something you're doing often, you could probably write some convenience functions to clean things up a bit.
     
  3. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Edit: this post does not contain any more information than Jesse's post

    Technical explanation (skip if you don't care :p):
    localEulerAngles and most other members of transform is a property. A property looks like a normal variable, but it is actually a function. This particular property returns a Vector3. Vector3 is a struct, which means that it always returned as a copy. All this means that the property localEulerAngles returns a copy of the rotation. The error is the compiler protecting you from assigning this value to a useless copy. If it didn't give the error, the code would do nothing.

    Solution:
    Always assign a full vector3 to the property:
    Code (csharp):
    1. transform.localEulerAngles = new Vector3(10,0,0);
     
    BenBart likes this.
  4. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    Thank you.

    So anytime you want to change the position or rotation of an object you must set its position equal to a new vector3? Is that the only way?
     
  5. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    It doesn't have to be a new vector3, but in C# you always need to assign a Vector3. Technically you can also use any of the Translate, Rotate, RotateAround or LookAt functions of Transform, but I don't think that that's what you're asking ;).
     
    Last edited: Oct 16, 2010
  6. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133


    Another question about this. Is there anyway to look at the actual 'transform.position' or 'transform.eulerAngles' function that gets called?

    or is there anywhere that documents everything this function does in C# specifically?

    and again thank you for the technical explanation, I do want to know whats going on behind the scenes of the code


    Also, I'm not exactly following the use of the 'new' tag in c#. In JS you could just do blah = Vector3(1,2,3). But it seems doing = Vector3(1,2,3) anything in C# gives an error and the 'new' tag is always need, whats the technical reason for that? Was JS automatically making a 'new' vector3 for something to be equal to without the need for the new tag to be there?
     
    Last edited: Oct 21, 2010
  7. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    No, you cannot view the source of these functions (except by buying a source code licensed version of Unity, which is probably not very realistic :p).

    Not really.

    You could get some generic idea of how such a thing could work by reading up on matrix transformations and quaternion math, but that does not give you information about what the specific functions do as they might simply be returning cashed values.



    New is obligatory by design in C#. Whenever you construct an object through one of its constructor functions, you need to use new. In JS, new is optional. JS will add it for you if you omit it. This is basically the key selling point of Unity's JS: it implements several workarounds to shorten code for things that are rather verbose in C# (like the issue from your initial post in this thread).

    When I said you don't need to add a new vector3, what I meant to say was that you could also use a vector you obtained from somewhere else, for example:
    Code (csharp):
    1. transform.localEulerAngles = someOtherTransform.localEulerAngles;
     
    Last edited: Oct 21, 2010
  8. halimozturk

    halimozturk

    Joined:
    Dec 1, 2012
    Posts:
    16
    Thanks Jesse this one worked fine for me.
     
  9. MattBee

    MattBee

    Joined:
    Aug 23, 2013
    Posts:
    27
    4 years later and still incredibly useful, this helped me a ton.
     
  10. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    add "f" to the floats in the solution

    Code (csharp):
    1. transform.localEulerAngles = new Vector3(10f,0f,0f);
     
  11. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    This necro makes me sad. Not due to the necro, but because OP's game never came out as far as I can tell:


    Interdimensional. Jesus. Velociraptor.
     
    MitchStan and ThermalFusion like this.
  12. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Maybe still in production? :)
     
  13. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    One can dream.