Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Turret movement and AI

Discussion in 'Scripting' started by Vitally, Nov 4, 2015.

  1. Vitally

    Vitally

    Joined:
    Aug 29, 2012
    Posts:
    8
    Hi all,

    I've been programming for a while now in unity and there has always been one thing i've avoided... and that's Rotation and Quaternions. I'm not good with math so to come into the world of Quaternions is a little overwhelming. Im working on a script to allow a CWIS gun object to automatically track, target, and engage flying game objects. This however introduces the issue of rotating to face an object. Normally I could get away with a transform.lookat() statement but that wont work in this case. I need to individually assign the azimuth and elevation to the different parts of the gun system. I've managed to get a piece of code working for the azimuth:
    Code (CSharp):
    1.  //aim the base
    2.         Vector3 lookPos = ObjectToTrack.transform.position - gunAsmuth.transform.position;
    3.         lookPos.y = 0;
    4.         Quaternion rotation = Quaternion.LookRotation(lookPos, Vector3.forward);
    5.         gunAsmuth.transform.rotation = Quaternion.Slerp(gunAsmuth.transform.rotation, rotation, Time.deltaTime * damping);
    and i'm happy with that behaviour. But now to do elevation I need the rotation to be done locally so the azimuth is preserved. I am totally stumped.
     
  2. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,772
    There's probably a better way to do this, but just offhand you could do this:

    Code (csharp):
    1.  
    2. Vector3 directionToTarget = (ObjectToTrack.transform.position- gunAsmuth.transform.position).normalized;
    3. float elevationAngle = Vector3.Angle( directionToTarget, lookPos.normalized );
    4.  
    5. Quaternion elevationRotation = Quaternion.Euler(elevationAngle,0,0);
    6.  
    7. // Then apply elevationRotation to the localRotation of the turret's barrel transform which should be a child object of the turret base.
    8.  
    This will only work for targets above the turret. If your turret can also aim down then you'll need to multiply the angle by the sign of the dot product for the turret's up vector and the directionToTarget Vector

    Code (csharp):
    1.  
    2. elevationAngle *= Mathf.Sign( Vector3.Dot( gunAsmuth.transform.up, directionToTarget ) );
    3.  

    Another thing to note is that your code will only work for turrets are on a flat surface. If they are on an angled surface then your lookPos won't be correct and my solution for the elevation will also be incorrect.
     
    Last edited: Nov 4, 2015
  3. Vitally

    Vitally

    Joined:
    Aug 29, 2012
    Posts:
    8
    Thanks so much! Your code works great! You have no idea how frustrating this problem was for me.