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 marnes · Jan 05, 2013 at 01:21 AM · c#vector3quaternion

Converting script from JS to C#

This snippet of code is from the BootCamp demo's SoldierController.js Update() where it tries to turn the character based on camera movement changes.

JS:

 soldierTransform.localRotation.eulerAngles.y = Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed);


C#: (FAIL)

 soldierTransform.localRotation.eulerAngles += new Vector3(0.0f,Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed),0.0f);

Error: Cannot modify the return value of 'UnityEngine.Transform.localRotation' because it is not a variable.

So I understand this thread: http://forum.unity3d.com/threads/6404-Cannot-modify-....-because-it-is-not-a-variable-in-C

But this is sort of a nested example -- modifying a Quaternion.Vector3 -- and I don't know how to get around this one. Anyone able to explain? Better yet, what would be a clean readable way to do this operation?

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

3 Replies

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

Answer by Bunny83 · Jan 05, 2013 at 02:23 AM

Well, who wrote that script has a really bad style of programming. I'm actually even wondering that it works in UnityScript.

What you want are the localEulerAngles.

 soldierTransform.localEulerAngles = soldierTransform.localEulerAngles + new Vector3(0.0f, Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed), 0.0f);

To understand what was wrong here's a quick explanation:

Whenever you put a dot behind a class or struct you read / access the reference.

So just the very first part of your line

 soldierTransform.localRotation

will read / use what ever is before the dot in this case the reference stored in soldierTransform.

localRotation is a property of the Transform class. A property is just syntactical sugar for a get and set method. So when ever you read a property the getter is called. When you assign something to the property the setter is called. The big problem are properties of value types like structs (Vector3, Quaternion). If the getter is called it will return a copy of the object. It can't return a reference since it's a value type.

Now take a look at the next part of your line:

 soldierTransform.localRotation.eulerAngles

Again because of the dot behind localRotation you will read localRotation. Since it's a property you will access a copy of the Quaternion. What ever you do with the eulerAngles property of the quaternion (read or write) will be done on the copy.

 soldierTransform.localRotation.eulerAngles += XXX

The += operator is the same as

 soldierTransform.localRotation.eulerAngles = soldierTransform.localRotation.eulerAngles + XXX;

So in the end you assign a new value to the eulerAngles property of a temporary copy of the localRotation Quaternion. This will effectively do nothing because the temporary copy will be lost after that operation. You never invoked the setter of localRotation to assign a new Quaternion.

In UnityScript the compiler automatically creates temp variables, read the current value, store them locally, do the changes and assign them back to the property .

soldierTransform.localRotation.eulerAngles += new Vector3(0.0f,Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed),0.0f);

Here's a nice example i've just tried. This line of UnityScript:

     // UnityScript
     transform.localRotation.eulerAngles.y = 5.0;

will translate to this actual code:

     // C#
     float y = 5f;
     Quaternion localRotation = this.transform.localRotation;
     Vector3 eulerAngles = localRotation.eulerAngles;
     float num = eulerAngles.y = y;
     Vector3 vector = localRotation.eulerAngles = eulerAngles;
     Quaternion quaternion = this.transform.localRotation = localRotation;

I just put this line of UnityScript into a project, built an standalone player and opened the Assembly-UnityScript.dll with ILSpy and let it decompile to C#

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 marnes · Jan 05, 2013 at 03:31 PM 0
Share

Thank you! This is why javascript is a dangerous language to be scripting with. At least with C#, you know what you are getting. It's too bad so many of the tech demos use js, thus the community does too.

avatar image Bunny83 · Jan 06, 2013 at 01:46 AM 1
Share

@marnes: Well, in the end it's about the same. You just have to know what you get when you do something. UnityScript is less strict but might produce some overhead you wouldn't expect. C# on the other hand might cause more frustration for people new to coding since the compiler would bash you until you have it right ;).

I wouldn't say that C# is the better language. If you really know UnityScript in all it's colors you can produce the same quality code you can with C# but UnityScript tend to produce a little bit overhead. I guess a major part is that the UnityScript compiler uses the Boo compiler to produce the .NET / $$anonymous$$ono assemblies, so it probably produces some kind of intermediate code for the Boo compiler.

avatar image
0

Answer by DaveA · Jan 05, 2013 at 01:24 AM

From that post you linked to, I would guess:

 soldierTransform.localRotation.eulerAngles = soldierTransform.localRotation.eulerAngles + new Vector3(0.0f,Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed),0.0f);
Comment
Add comment · Show 3 · 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 Davidovich · Jan 05, 2013 at 01:56 AM 0
Share

If that also causes a problem, you can try:

Vector3 soldierAngles = soldierTransform.localRotation.eulerAngles;
soldierAngles += new Vector3(0.0f,$$anonymous$$athf.$$anonymous$$oveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed),0.0f);
soldierTransform.localRotation.eulerAngles = soldierAngles;
avatar image Bunny83 · Jan 05, 2013 at 02:24 AM 0
Share

@$$anonymous$$ovich: That won't work either ;) see my answer

avatar image Davidovich · Jan 05, 2013 at 02:43 AM 0
Share

@Bunny83: Nice catch. I wasn't aware that Quaternions were a struct too.

avatar image
0

Answer by Imankit · Jan 05, 2013 at 10:28 AM

 soldierTransform.localRotation.eulerAngles = new Vector3(soldierTransform.localRotation.eulerAngles.x,Mathf.MoveTowards(currentAngle, currentAngle + delta, Time.deltaTime * maxRotationSpeed),soldierTransform.localRotation.eulerAngles.z);




This will definitely work...

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 Bunny83 · Jan 05, 2013 at 01:06 PM 0
Share

No, this won't work since localRotation returns a copy of a valuetype. Unity even throws an error:

 error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.localRotation'. Consider storing the value in a temporary variable

It will work in UnityScript because the compiler does the temp-var caching behind the scenes. See the last example in my answer.

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

calculating looking angle between 2 transforms 0 Answers

Slerp look at direction not working... 3 Answers

Rotate player (rigidbody) towards his movement 2 Answers

Pose.ctor - create pose from vector3 and quaternion 1 Answer

How to add 2 Quaternions. 2 Answers


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