Just out of curiosity. Can any of you think of any faster way to match forward direction between two gameobjects?
Here are the results I got so far using System.Diagnostics Stopwatch and iterating over this 1 million times (on my PC). The transform of both objects have been cached prior to the iterations.
// Method 1 is ~1293ms
ObjectA.forward = ObjectB.forward; // 1293ms
// Method 2 is ~1094ms
Quaternion ObjectA_Rotation = ObjectA.rotation; // 36ms
ObjectA.rotation = new Quaternion(ObjectA_Rotation.x, ObjectB.rotation.y, ObjectA_Rotation.z, ObjectA_Rotation.w); // 1058ms
// Changing the rotation of an object is the most time consuming part
ObjectA.rotation = new Quaternion(0, 0, 0, 0); // 876ms
// Note: If the Gameobject has a collider + rigidbody attached, I get the result above. However, if i remove the rigidbody and collider, this same ObjectA.rotation = new Quaternion(0, 0, 0, 0); // 147ms.
You may find the the Quaternion constructor has an overhead here. Given that Quaternion is a struct, you can just declare a variable and then assign the fields individually. Also, is there some reason why you are avoiding just using ObjectA.rotation = ObjectB.rotation?
Object B is an empty game object with a NavMeshAgent attached to it. Object A is a Game object representing a character with Collider and Rigidbody attached.
Now since NavMeshAgents don’t follow terrain / surface normals, Object A is simply following this invisible Object B matching its position but only Y rotation since X and Z rotations are driven by the collider / Rigidbody.
So in reality, I am only trying to match the Y rotation of B with A but in the process became curious if there was a better alternative.
In terms of the Quaternion setup cost, there is but it isn’t too bad. What I found interesting is the substantial difference in setting up this Quternion when a collider and Rigidbody is attached to this game object as per my post above.
When rotating an object that has a collider rigidbody, there is a significant difference in performance between using transform.rotation vs. rigidbody.rotation. Again these results are while iterating over each of these 1 million times.
// With both Transform and Rigidbody references cached
myTransform.rotation = new Quaternion(0, 0, 0, 0); // 876.0ms
myRigidbody.rotation = new Quaternion(0, 0, 0, 0); // 79.41ms
That is 10X the performance difference and the same holds true for transform.position vs. rigidbody.position. So when others suggested to use forces or the rigidbody equivalent functions to perform those rotations or translations, it’s a really good suggestion
You iterate 1M times with always the same values (0,0,0,0) ? Does it make a difference if you use different values each time?
Could it be, that some of the object.rotation or object.position methods will return without to do any “movement” if no value has changed? And the other (slower one) would do calculations without delta check (check if something has changed) to get better performance in real situations?
“If you change the rotation of a Rigibody using Rigidbody.rotation, the transform will be updated after the next physics simulation step. This is faster than updating the rotation using Transform.rotation, as the latter will cause all attached Colliders to recalculate their rotation relative to the Rigidbody.”