Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 LunaArgenteus · Oct 21, 2013 at 08:58 PM · rotationtransformquaternionvectorefficiency

Efficiency of transform.forward, up, and right

When you are moving around a game object, does anyone know if the transform vectors are updated every time rotation or local rotation is, or if the property calculates the rotated vector every time you access it?

If I need to call the global forward vector numerous times per update without changing the rotation in between, I'd rather store transform.forward in a separate Vector3 rather than having Unity calculate transform.rotation*Vector3.forward every time I call transform.forward.

I don't have Unity Pro, otherwise I'd benchmark it with the profiler myself . . .

I know I can always just take the precaution anyways, but it'd be nice to know for reference anyways. Thanks in advance!

Comment
Add comment · Show 4
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 Eric5h5 · Oct 21, 2013 at 09:47 PM 3
Share

You don't need Unity Pro to run benchmarks. Just use some kind of timer; Time.realtimeSinceStartup is fine. Or the Stopwatch class.

avatar image robertbu · Oct 21, 2013 at 11:02 PM 3
Share

But I just ran a quick test of three different methods using a single game object doing 10,000,000 iterations of each. $$anonymous$$ultiple runs average out to around:

 v3 = transform.forward:  625 miliseconds
 v3 = transform.TransformDirection(Vector3.forward): 550 miliseconds
 v3 = v3Forward: 25 miliseconds
avatar image Benproductions1 · Oct 22, 2013 at 12:11 AM 1
Share

I'm guessing thats because of certain performance differences when using properties ins$$anonymous$$d of functions. 600ms is really not much for 10mil iterations, so it does seem like very $$anonymous$$or performance differences should scale to a 75ms difference

avatar image LunaArgenteus · Oct 22, 2013 at 01:30 AM 0
Share

Eric, I suppose that's true. I'll keep the stopwatch class in $$anonymous$$d if I need tests in the future.

Rorbertbu, thanks for going through the trouble of testing it out some for me.

2 Replies

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

Answer by Bunny83 · Oct 21, 2013 at 10:07 PM

Well, for example the forward property is defined as:

     public Vector3 forward
     {
         get { return this.rotation * Vector3.forward; }
         set { this.rotation = Quaternion.LookRotation(value); }
     }

So when reading the forward vector Unity reads the rotation property and multiplies it with (0,0,1)

"rotation" is defined as

     public Quaternion rotation
     {
         get
         {
             Quaternion result;
             this.INTERNAL_get_rotation(out result);
             return result;
         }
         set
         {
             this.INTERNAL_set_rotation(ref value);
         }
     }

and the Quaternion - Vector multiplication looks like:

 public static Vector3 operator *(Quaternion rotation, Vector3 point)
 {
     float num = rotation.x * 2f;
     float num2 = rotation.y * 2f;
     float num3 = rotation.z * 2f;
     float num4 = rotation.x * num;
     float num5 = rotation.y * num2;
     float num6 = rotation.z * num3;
     float num7 = rotation.x * num2;
     float num8 = rotation.x * num3;
     float num9 = rotation.y * num3;
     float num10 = rotation.w * num;
     float num11 = rotation.w * num2;
     float num12 = rotation.w * num3;
     Vector3 result;
     result.x = (1f - (num5 + num6)) * point.x + (num7 - num12) * point.y + (num8 + num11) * point.z;
     result.y = (num7 + num12) * point.x + (1f - (num4 + num6)) * point.y + (num9 - num10) * point.z;
     result.z = (num8 - num11) * point.x + (num9 + num10) * point.y + (1f - (num4 + num5)) * point.z;
     return result;
 }

So what happens on the managed side is quite clear and not that much calculations. However we don't know what happens in "INTERNAL_get_rotation" since it's a native code function. It might request an update of all parents to actually calculate the quaternion. We simply don't know.

So in general if you use one of these properties multiple times inside the same function, store it in a local variable. As you already said that of course makes only sense if the value doesn't change between the different uses inside the function.

Comment
Add comment · Show 9 · 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 Benproductions1 · Oct 21, 2013 at 10:34 PM 1
Share

Global positions and rotations are most likely calculated with a recursive function that goes up the hierarchy, so thats probably what INTERNAL_get_rotation does

avatar image LunaArgenteus · Oct 22, 2013 at 01:24 AM 0
Share

I was wondering how you got such detailed code, but I managed to figure it out: I had no idea you could go to the declaration of Unity's defined functions and check out the internal Unity code. Doing so tells me exactly what I wanted to know! Thanks!

avatar image Bunny83 · Oct 22, 2013 at 06:24 AM 0
Share

@LunaArgenteus:
Well, just use ILSpy ;)

@Benproductions:
Well, i'm pretty sure that Unity will cache the result internally, but you will never know unless we would get some insight from UT (which is very unlikely to happen) ;)

avatar image Hoeloe · Oct 22, 2013 at 07:19 AM 0
Share

You did miss off the fact that transform itself is not cached. Unity, rather counter-intuitively, uses a GetComponent call to find the Transform attached to a GameObject each time you refer to the transform property, which is where I suspect a lot of the overhead is going.

avatar image Benproductions1 · Oct 22, 2013 at 08:02 AM 0
Share

@Hoeloe Yep! Thats why I presume they aren't caching anything else either. They provide the base functionality and allow the user to expand. In some cases I don't want/need to cache, so I don't ;)

Show more comments
avatar image
2
Wiki

Answer by Benproductions1 · Oct 21, 2013 at 10:03 PM

Hello,

Although I am presuming some design decisions about Unity, this is what it should be like.

transform.forward is the same as doing transform.TransformDirection(Vector3.foward), which is the same as doing transform.rotation*Vector3.forward

Doing transform.eulerAngles = angles is the same as doing transform.rotation.Set(Quaternion.Euler(angles))

Any global properties such as position and rotation are defined as so:

 function get rotation() : Quaternion {
     if (parent) {
         return localRotation * parent.rotation;
     }
     return localRotation;
 }
 
 function get position() : Vector3 {
     if (parent) {
         return parent.TransformPoint(localPosition);
     }
     return localPosition;
 }
 
 function TransformPoint() : Vector3 {
     return rotation * Vector3.Scale(lossyScale, position);
 }

I know that I'm not 100% right, but the general idea stands. Unless you are accessing local spacial information, you are recursively calculating it. Every time.

Hope this helps,
Benproductions1

PS: I'm going to keep this as a community Wiki so people can fix my code ;)

Comment
Add comment · 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

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

18 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

Related Questions

Object not rotating when the associated trigger is triggered 1 Answer

How to make Y-Axis face away from a position? 2 Answers

player rotation to follow the mouse 2 Answers

Instantiate GameObject towards player 0 Answers

Random.rotationUniform clarification 4 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