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 /
This question was closed Feb 01, 2015 at 06:53 PM by Glurth for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Glurth · Jan 01, 2015 at 06:40 PM · transformgetcomponentrotations

Why won’t GetComponent ().rotation.SetLookRotation actually change the object’s rotation?

I have some code to modify an object’s rotation transform in the update statement, but I’m not getting the results I expected … This code snipped, run in Update(), works fine and rotates the object as expected:

 Transform t = GetComponent<Transform> ();
 Quaternion q = new Quaternion ();
 q.SetLookRotation(lookat,new Vector3 (0, 1, 0));
 t.rotation = q;

This code does NOT rotate the object. Why the heck not?

 GetComponent<Transform> ().rotation.SetLookRotation(lookat,new Vector3 (0, 1, 0));

Note: lookat is a Vector3 variable setup earlier in the code: setup not relevant, I think, because I pass the same values to both versions of the code. (Debug.Log tests confirmed this)

I suspect I’m missing something simple and obvious here, but I’m still stumped.

Comment
Add comment · Show 5
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 Owen-Reynolds · Jan 01, 2015 at 08:04 PM 1
Share

Just transform is a shortcut for GetComponent transform(). Other common components have similar shortcuts. LookAt is also a shortcut. transform.LookAt(lookat); does the same as both examples.

But, even though most people would never write it that way, your 2nd example should work. Does it fail in a script by itself?

avatar image Glurth · Jan 01, 2015 at 08:54 PM 0
Share

I'm not sure I understand your first paragraph..

Yes, it does fail in a script by itself. this fails to rotate the object

 void Update () {
             GetComponent<Transform> ().rotation.SetLookRotation(new Vector3 (1, 0, 1),new Vector3 (0, 1, 0));
     }

this DOES rotate the object

 void Update () {
             Quaternion q = new Quaternion ();
             q.SetLookRotation(new Vector3 (1, 0, 1),new Vector3 (0, 1, 0));
             GetComponent<Transform> ().rotation = q;
     }








avatar image Namey5 · Jan 01, 2015 at 09:05 PM 0
Share

He means that there is an in-built reference to transform, so you do not have to call it manually, i.e.

 gameObject.transform.rotation.SetLookRotation(new Vector3(1,0, 1), new Vector3 (0, 1, 0));

Having this by itself and with gameObject, ins$$anonymous$$d of GameObject (case sensitive), will access the transform component of the object the script is attached to. Likewise, if you wanted to get the transform of another object, you would put your reference to that object in place of gameObject.

avatar image Glurth · Jan 01, 2015 at 09:15 PM 0
Share

oh my, that's very useful! Alas: these also fails to rotate the object

 gameObject.transform.rotation.SetLookRotation(new Vector3 (1, 0, 1),new Vector3 (0, 1, 0));

and

 transform.rotation.SetLookRotation(new Vector3 (1, 0, 1),new Vector3 (0, 1, 0));

this DOES (notice: I'm not even creating a new instance of a quaternion here, just using a local variable for no reason I can see)!

 Quaternion q = transform.rotation;
 q.SetLookRotation(new Vector3 (1, 0, 1),new Vector3 (0, 1, 0));
 transform.rotation = q;
avatar image Owen-Reynolds · Jan 02, 2015 at 01:14 AM 0
Share

There's also no reason to use SetLookRotation. Using transform.LookAt will run it for you, using your rotation (see the docs.)

SetLookRotation is for those rare cases when you are doing math on just naked quaterions.

Also don't need to use new Vector3(0,1,0) as the 2nd input. Vector3.up is a shortcut. But, Up is the default anyway, so don't even need a 2nd input (you rarely need a rotation vector which isn't "head up.")

1 Reply

  • Sort: 
avatar image
1
Best Answer

Answer by Owen-Reynolds · Jan 02, 2015 at 01:43 AM

I think your not-working examples are really compile errors, which the compiler should be flagging, but isn't. The same sort of error as transform.position.x=5;. What compiler are you using?

rotation is a struct and transform.rotation is probably a set/get. That means you can change the entire thing using set, or play with a copy through get. I assume the compiler didn't notice that SetLookRotation is changing itself, so didn't flag anything. It just (incorrectly) said "here's your rotation copy, have fun."

Why doesn't C# allow references to structs, like C++? I assume it would break garbage collection. Likewise, C# doesn't have a const for member funcs, which might allow it to catch this easier.

Comment
Add comment · Show 4 · 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 Glurth · Jan 02, 2015 at 02:51 AM 0
Share

Oh, so the object.transform.rotation is only returning a copy to the transform, not a reference to the transform? I didn't expect that, in c# I though everything, except base types, is supposed to be a reference. Is that the case with all "get" accessors?

I'm a bit confused though: How would the compiler know if the SetLookRotation() function is going to modify itself?
How am I as a programmer supposed to know if a variable I'm trying to use comes from a get accessor, and I only have a copy? Check the docs each time? This makes me think your right, the compiler SHOULD be at least warning me here.

I'm using monoDevelop that came with Unity.

avatar image Owen-Reynolds · Jan 02, 2015 at 06:38 AM 1
Share

Structs in C# are never references. Classes always are. Just because. Some C# programmers say they avoid structs, just to avoid non-referenced non-primatives. I assume Unity uses structs for speed.

The issue is only when "reaching through" a getter to a modify a struct. Again, same problem as transform.position.x=5;.

But, most people use the Unity shortcuts and never have to worry about this. You may be the only person to ever use SetLookRotation through a transform. Come to think of it, I only use LookRotation, which is the value-returning version.

avatar image Glurth · Jan 02, 2015 at 04:01 PM 0
Share

The issue is only when "reaching through" a getter to a modify a struct

Since the get is transparent to a caller, how do I know if what I'm using IS or IS-NOT safe to modify? $$anonymous$$anually check the definition, in code, or library, to see if the variable I'm using is indeed a getter (though auto fill DOES help with this part), and further deter$$anonymous$$e if the return value is a Sruct or class? Fix my compiler?

Thanks for the terrific explanations and help Owen!

Edit: Ran tests using visual studio- while directly modifying a "gotten" struct value with an "=" WILL generate an error, calling a member function on the "gotten" value will not. It seems to me, like the compiler would need some kind of keyword to $$anonymous$$NOW weather or not a struct's particular member function actually modifies it's values, or not, in order to be able to generate a compiler error here. They obviously thought about this when designing c#, so why no modifier/keyword?

 struct someStruct {
         public float f;
         /*keyword $$anonymous$$ODIFIER*/ public void SetF(float param){f=param;}
         public void OutputDebugInfo(float another_number) {Debug.output(f+another_number);}
     }
     class hasAccessor$$anonymous$$ember    {
         private someStruct a;
         public someStruct A    {
             get
             {return a;}
             set
             {a=value;}
         }
     }
     class test{
         void main(){
             hasAccessor$$anonymous$$ember has= new hasAccessor$$anonymous$$ember();
             has.A.f = 6.0f;  //compiler error on this line  Cannot modify the return value of 'hasAccessor$$anonymous$$ember.A' because it is no a variable
             has.A.SetF(6.0f);   // no error generated- but there should be because modification is done
             has.A.OutputDebugInfo(12.0f);  // no error generated- nor SHOULD there be
         }
     }
avatar image Owen-Reynolds · Jan 02, 2015 at 05:23 PM 0
Share

I think this is just a defect in C#, and kind of a bad one. This is the same problem: http://blogs.msdn.com/b/colinth/archive/2007/05/14/c-for-c-users-structs-vs-classes.aspx not being caught by the compiler.

But, in practice, I think this is rare in Unity. I've never seen it before this. Your very 1st example "pull out, modify, put back" is often more natural, since $$anonymous$$odify may be several steps.

Follow this Question

Answers Answers and Comments

27 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

Related Questions

I can't update my speed after reaching certain score 1 Answer

Accessing a GameObject from another script 1 Answer

How to get all children gameobjects 5 Answers

Raycast to Disable Script 0 Answers

Neutralising child rotations -> Parent 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