Search Unity

Turret rotation along individual axis using RotateTowards

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

  1. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    9
    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,556
    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:
    9
    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,556
    ... and you are using different, nested objects for base and launchers (one level for each axis)?
     
  5. Meany747

    Meany747

    Joined:
    Jun 13, 2017
    Posts:
    9
    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,556
    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:
    9
    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:
    9
    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