Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Quaternion.LookRoation() don't want to function properly?

Discussion in 'Scripting' started by DaKocha, Dec 7, 2013.

  1. DaKocha

    DaKocha

    Joined:
    Oct 7, 2012
    Posts:
    28
    Here's my entire modified SmoothLookAt script.
    However, something's wrong and the turret wont rotate "fully" when the "local mode" is enabled.


    Code (csharp):
    1. var target : Transform;
    2. var local : boolean = true;
    3. var damping = 6.0;
    4. var smooth = true;
    5.  
    6. var xMin : float = 0;
    7. var xMax : float = 0;
    8.  
    9. var yMin : float = 0;
    10. var yMax : float = 0;
    11.  
    12. var zMin : float = 0;
    13. var zMax : float = 0;
    14.  
    15. var clampX : boolean = false;
    16. var clampY : boolean = false;
    17. var clampZ : boolean = false;
    18.  
    19.  
    20. var x : boolean = true;
    21. var y : boolean = true;
    22. var z : boolean = true;
    23.  
    24. private var xA : float;
    25. private var yA : float;
    26. private var zA : float;
    27.  
    28. var debug : boolean = false;
    29.  
    30. var debugBox : GameObject;
    31.  
    32.  
    33. @script AddComponentMenu("Camera-Control/Smooth Look At")
    34.  
    35. function LateUpdate () {
    36.     if (target) {
    37.         if (smooth)
    38.         {
    39.        
    40.         if (local) {
    41.        
    42.             xA = transform.localEulerAngles.x;
    43.             zA = transform.localEulerAngles.y;
    44.             zA = transform.localEulerAngles.z;
    45.            
    46.             // Look at and dampen the rotation
    47.             var rotation : Vector3 = Quaternion.LookRotation(transform.InverseTransformPoint(target.position)).eulerAngles;
    48.            
    49.             if (clampX) rotation.x = Clamp(rotation.x, xMin, xMax);
    50.             if (clampY) rotation.y = Clamp(rotation.y, yMin, yMax);
    51.             if (clampZ) rotation.z = Clamp(rotation.z, zMin, zMax);
    52.  
    53.             transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(rotation), Time.deltaTime * damping);
    54.            
    55.             if (!x) transform.localEulerAngles.x = xA;
    56.             if (!y) transform.localEulerAngles.y = yA;
    57.             if (!z) transform.localEulerAngles.z = zA;
    58.            
    59.         }
    60.         else {
    61.        
    62.             xA = transform.localEulerAngles.x;
    63.             zA = transform.localEulerAngles.y;
    64.             zA = transform.localEulerAngles.z;
    65.            
    66.             // Look at and dampen the rotation
    67.             var rotation2 : Vector3 = Quaternion.LookRotation(target.position-transform.position).eulerAngles;
    68.  
    69.             if (clampX) rotation2.x = Clamp(rotation2.x, xMin, xMax);
    70.             if (clampY) rotation2.y = Clamp(rotation2.y, yMin, yMax);
    71.             if (clampZ) rotation2.z = Clamp(rotation2.z, zMin, zMax);
    72.  
    73.             //transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation2), Time.deltaTime * damping);
    74.             transform.rotation = Quaternion.Euler(rotation2);
    75.            
    76.             if (!x) transform.localEulerAngles.x = xA;
    77.             if (!y) transform.localEulerAngles.y = yA;
    78.             if (!z) transform.localEulerAngles.z = zA;
    79.                    
    80.         }
    81.        
    82.         }
    83.         else
    84.         {
    85.             // Just lookat
    86.             transform.LookAt(target);
    87.         }
    88.     }
    89.     if (debug) Debug.Log(transform.InverseTransformPoint(target.position).ToString()+"   "+transform.worldToLocalMatrix.MultiplyPoint3x4(target.position));
    90.     if (debugBox) debugBox.transform.localPosition = transform.InverseTransformPoint(target.position);
    91. }
    92.  
    93. function Start () {
    94.  
    95.     if (xMin < 0) xMin = 360-Mathf.Abs(xMin);
    96.     if (yMin < 0) yMin = 360-Mathf.Abs(yMin);
    97.     if (zMin < 0) zMin = 360-Mathf.Abs(zMin);
    98.    
    99.     if (xMin == 0  xMax == 0) clampX = false;
    100.     else clampX = true;
    101.    
    102.     if (yMin == 0  yMax == 0) clampY = false;
    103.     else clampY = true;
    104.    
    105.     if (zMin == 0  zMax == 0) clampZ = false;
    106.     else clampZ = true;
    107.    
    108.    
    109.     // Make the rigid body not change rotation
    110.     if (rigidbody)
    111.         rigidbody.freezeRotation = true;
    112. }
    113.  
    114. function Clamp (val : float, min : float, max : float) : float {
    115.  
    116.     if (val < min  val > 180) return min;
    117.     else if (val > max  val < 180) return max;
    118.     else return val;
    119.    
    120.     return val;
    121.  
    122. }
     
  2. DaKocha

    DaKocha

    Joined:
    Oct 7, 2012
    Posts:
    28
    To clarify things, here goes some lil' more stuff
    $glitch.jpg
     
  3. DaKocha

    DaKocha

    Joined:
    Oct 7, 2012
    Posts:
    28
    The problem is solved thanks to GameVortex who pointed out the error for me :)

    BTW, here's the *working* code

    Code (csharp):
    1. var target : Transform;
    2. var local : boolean = true;
    3. var damping = 6.0;
    4. var smooth = true;
    5.  
    6. var xMin : float = 0;
    7. var xMax : float = 0;
    8.  
    9. var yMin : float = 0;
    10. var yMax : float = 0;
    11.  
    12. var zMin : float = 0;
    13. var zMax : float = 0;
    14.  
    15. var clampX : boolean = false;
    16. var clampY : boolean = false;
    17. var clampZ : boolean = false;
    18.  
    19.  
    20. var x : boolean = true;
    21. var y : boolean = true;
    22. var z : boolean = true;
    23.  
    24. private var xA : float;
    25. private var yA : float;
    26. private var zA : float;
    27.  
    28.  
    29. @script AddComponentMenu("Camera-Control/Smooth Look At")
    30.  
    31. function LateUpdate () {
    32.     if (target) {
    33.         if (smooth)
    34.         {
    35.        
    36.         if (local  (transform.parent != null)) {
    37.        
    38.             xA = transform.localEulerAngles.x;
    39.             zA = transform.localEulerAngles.y;
    40.             zA = transform.localEulerAngles.z;
    41.            
    42.             // Look at and dampen the rotation
    43.             var rotation : Vector3;
    44.            
    45.             rotation = Quaternion.LookRotation(transform.parent.InverseTransformPoint(target.position)).eulerAngles;
    46.             // or better rotation = Quaternion.LookRotation(transform.parent.InverseTransformDirection(target.position - transform.position)).eulerAngles;
    47.            
    48.            
    49.             if (clampX) rotation.x = Clamp(rotation.x, xMin, xMax);
    50.             if (clampY) rotation.y = Clamp(rotation.y, yMin, yMax);
    51.             if (clampZ) rotation.z = Clamp(rotation.z, zMin, zMax);
    52.  
    53.             transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(rotation), Time.deltaTime * damping);
    54.            
    55.             //transform.localRotation = Quaternion.Euler(rotation);
    56.            
    57.             if (!x) transform.localEulerAngles.x = xA;
    58.             if (!y) transform.localEulerAngles.y = yA;
    59.             if (!z) transform.localEulerAngles.z = zA;
    60.            
    61.         }
    62.        
    63.         else {
    64.        
    65.             xA = transform.localEulerAngles.x;
    66.             zA = transform.localEulerAngles.y;
    67.             zA = transform.localEulerAngles.z;
    68.            
    69.             // Look at and dampen the rotation
    70.             var rotation2 : Vector3 = Quaternion.LookRotation(target.position-transform.position).eulerAngles;
    71.  
    72.             if (clampX) rotation2.x = Clamp(rotation2.x, xMin, xMax);
    73.             if (clampY) rotation2.y = Clamp(rotation2.y, yMin, yMax);
    74.             if (clampZ) rotation2.z = Clamp(rotation2.z, zMin, zMax);
    75.  
    76.             //transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation2), Time.deltaTime * damping);
    77.             transform.rotation = Quaternion.Euler(rotation2);
    78.            
    79.             if (!x) transform.localEulerAngles.x = xA;
    80.             if (!y) transform.localEulerAngles.y = yA;
    81.             if (!z) transform.localEulerAngles.z = zA;
    82.                    
    83.         }
    84.        
    85.         }
    86.         else
    87.         {
    88.             // Just lookat
    89.             transform.LookAt(target);
    90.         }
    91.     }
    92. }
    93.  
    94. function Start () {
    95.  
    96.     if (xMin < 0) xMin = 360-Mathf.Abs(xMin);
    97.     if (yMin < 0) yMin = 360-Mathf.Abs(yMin);
    98.     if (zMin < 0) zMin = 360-Mathf.Abs(zMin);
    99.    
    100.     if (xMin == 0  xMax == 0) clampX = false;
    101.     else clampX = true;
    102.    
    103.     if (yMin == 0  yMax == 0) clampY = false;
    104.     else clampY = true;
    105.    
    106.     if (zMin == 0  zMax == 0) clampZ = false;
    107.     else clampZ = true;
    108.    
    109.    
    110.     // Make the rigid body not change rotation
    111.     if (rigidbody)
    112.         rigidbody.freezeRotation = true;
    113. }
    114.  
    115. function Clamp (val : float, min : float, max : float) : float {
    116.  
    117.     if (val < min  val > 180) return min;
    118.     else if (val > max  val < 180) return max;
    119.     else return val;
    120.    
    121.     return val;
    122.  
    123. }
     
  4. GameVortex

    GameVortex

    Joined:
    Jun 14, 2013
    Posts:
    12
    You wanted me to elaborate a bit on the InverseTransformDirection here, so here I am. =)

    The reason why I said that a Direction would be better is because unlike LookAt the LookRotation requires a Direction to face instead of a point to face. In your script supplying a point works probably because your turret is in the center (0,0,0) of the parents coordinate system, so a point in that space is therefore also a direction for the turret. If you move your turret away from the center it would no longer face the correct direction, but rather face an imaginary point offset by the same amount the turret has been offset from the center.

    Calculating the correct local direction with InverseTransformDirection will solve that problem as we also take into account the position of the turret.

    Hope this makes sense, I tend to ramble a bit. =P
     
  5. DaKocha

    DaKocha

    Joined:
    Oct 7, 2012
    Posts:
    28
    Now that makes some sense finally!

    Thanks for your kind time :)

    Regards