Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Turret rotation along individual axis using RotateTowards

Discussion in 'Scripting' started by Meany747, Jul 22, 2019.

  1. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    8
    Hello all, I have been building and rebuilding this script for a while now and I am now out of ideas.

    This script is attached to turret components and rotates them to face the player (m_target). My issue is that the only portion of the script that appears to work correctly is the rotation around the Y axis. Z and X twist the rotation, getting somewhat close to the player but ignoring their constraints. I feel this will simply be changing a single line of code to get it working.

    Code (CSharp):
    1. void Update () {
    2.  
    3.         currentAngles = transform.rotation.eulerAngles;
    4.  
    5.         if (m_target != null) {    //If there's a target slowly rotate towards
    6.  
    7.  
    8.         //    if(transform.rotation != lookAtRotation) {
    9.             if (singleAxis == true) {
    10.                 targetAngles = (m_target.transform.position - transform.position).normalized;
    11.  
    12.                 if (yAxis == true) {      
    13.                     //WORKING ROTATE
    14.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, 0, targetAngles.z), Vector3.up);
    15.                     transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    16.                     //END WORKING ROTATE
    17.                 }
    18.  
    19.                 if (xAxis == true) {
    20.                     //WORKING ROTATE
    21.                     //targetAngles = (m_target.transform.position - transform.position).normalized;
    22.                     //lookAtRotation = Quaternion.LookRotation (new Vector3 (0 , targetAngles.y, targetAngles.z), Vector3.right);
    23.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (0, targetAngles.y, targetAngles.z), Vector3.up);
    24.                     transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    25.                     //END WORKING ROTATE
    26.                 }
    27.  
    28.                 if (zAxis == true) {
    29.  
    30.                     //WORKING ROTATE
    31.                     //targetAngles = (m_target.transform.position - transform.position).normalized;
    32.                     //lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, targetAngles.y, 0), Vector3.forward);
    33.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, targetAngles.y, 0), Vector3.up);
    34.                     transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    35.                     //END WORKING ROTATE
    36.                 }
    37.             } else if (singleAxis != true) {
    38.                 Debug.Log ("Single axis not true");
    39.                 lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, 0, targetAngles.z), Vector3.up);
    40.             }
    41.             //}
    42.  
    43.  
    44.  
    45.             if (transform.rotation == lookAtRotation && loaded == true && launcherAttached == true) {
    46.                 if (securityBot == true) {
    47.                     loaded = false;
    48.                     Debug.Log ("Fire!!");
    49.                     launcherScript.Fire ();
    50.                 }
    51.  
    52.                 if (militaryBot == true) {
    53.                     loaded = false;
    54.                     milBotAnim.SetBool ("MissilesGo", true);
    55.                     Debug.Log ("AIMED MISSILES");
    56.                     if (milBotAnim.GetCurrentAnimatorStateInfo(1).IsName("DeployedMissileRacksMilitaryBot")) {
    57.                         Debug.Log ("FIRE ZE MISSILES");
    58.                         launcherScript.Fire ();
    59.                     }
    60.                 }
    61.             }
    62.  
    63.             if (loaded == false && launcherAttached == true) {
    64.                 rTimer += Time.deltaTime;
    65.                 if (rTimer >= reloadTime) {
    66.                     loaded = true;
    67.                     rTimer = 0f;
    68.                 }
    69.             }
    70.         }
    71.  
    72.         if (m_target == null) {    //If there are no targets, face front
    73.             lookAtRotation = Quaternion.LookRotation (hullForward.transform.forward);
    74.             if (transform.rotation != lookAtRotation) {
    75.                 transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    76.             }
    77.         }
    78.     }

    Each boolean If statement should only allow rotation along that axis/handle
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,393
    You'll have a much easier time if you took the turret apart into two parts: base and Barrel. Then parent the Barrel to the base. Only rotate the turret around y (will rotate the Barrel with it), and rotate the rarrel LOCALLY around x.
     
  3. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    8
    That is exactly what this script is for. It allows for the base of the gun to rotate on the Y axis to face the player but does not rotate properly on the X or Z axis to change the pitch and yaw.

    Turret.PNG

    The dome base rotates on the Y axis here, facing the top launcher segment to the target, which in turn needs to rock up and down on the X axis to target the player. For now I have no idea why the X or Z axis segment of the script is not working.

    So the question is, how do I use LookRotation below to work on the X and Z angles?

    Code (CSharp):
    1. if (xAxis == true) {
    2.                     //WORKING ROTATE
    3.                     //targetAngles = (m_target.transform.position - transform.position).normalized;
    4.                     //lookAtRotation = Quaternion.LookRotation (new Vector3 (0 , targetAngles.y, targetAngles.z), Vector3.right);
    5.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (0, targetAngles.y, targetAngles.z), Vector3.up);
    6.                     transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    7.                     //END WORKING ROTATE
    8.                 }
    9.                 if (zAxis == true) {
    10.                     //WORKING ROTATE
    11.                     //targetAngles = (m_target.transform.position - transform.position).normalized;
    12.                     //lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, targetAngles.y, 0), Vector3.forward);
    13.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (targetAngles.x, targetAngles.y, 0), Vector3.up);
    14.                     transform.rotation = Quaternion.RotateTowards (transform.rotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    15.                     //END WORKING ROTATE
    16.                 }
     
    Last edited: Jul 22, 2019
  4. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,393
    ... and you are using different, nested objects for base and launchers (one level for each axis)?
     
  5. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    8
    Yes exactly, the triangular launchers above are a child of the dome shaped base, which is a child to the rest of the unit.

    So as you said it's the local x and z rotations trying to aim at the player which are causing the issue.
     
    Last edited: Jul 22, 2019
  6. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,393
    I'm not sure I see the bit in your code where you are using transform.localrotation
     
  7. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    8
    Good point, I've made a modification

    Code (CSharp):
    1. if (xAxis == true) {
    2.                     //WORKING ROTATE
    3.                     //targetAngles = (m_target.transform.position - transform.position).normalized;
    4.                     //lookAtRotation = Quaternion.LookRotation (new Vector3 (0 , targetAngles.y, targetAngles.z), Vector3.right);
    5.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (0, targetAngles.y, targetAngles.z), Vector3.up);
    6.                     transform.localRotation = Quaternion.RotateTowards (transform.localRotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    7.                     //END WORKING ROTATE
    8.                 }
    The issue here is that when the player moves close to the turret, it fires straight down into the ground, moving further away fires straight into the air, with a sweet spot in the mid range.
     
    Last edited: Jul 22, 2019
  8. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    8
    Ok, now let this be a lesson to people who get stuck in their own head. Ask for help. Even the simplest suggestion can potentially solve the issue.

    Here is what appears to be a functioning X rotation script of a child object:

    Code (CSharp):
    1.  
    2. if (xAxis == true) {
    3.                     //WORKING ROTATE FOR CHILD
    4.                     targetAngles = transform.localPosition - m_target.transform.position;
    5.                     targetAngles.y += childHeight;    //Height adjustment to not fire over target
    6.  
    7.                     lookAtRotation = Quaternion.LookRotation (new Vector3 (0, -targetAngles.y, targetAngles.z), Vector3.up);
    8.                     transform.localRotation = Quaternion.RotateTowards (transform.localRotation, lookAtRotation, rotationSpeed * Time.deltaTime);
    9.                     //END WORKING ROTATE
    10.                 }
    11.  
    I know the targetAngles calculation feels backwards, but through testing it yields the right result.

    Thanks a lot Franz, you helped immensely by making me step back from the problem.
     
    Last edited: Jul 22, 2019
unityunity