Search Unity

How to make a turret AI in Unity

Discussion in '2D' started by Leandro95, Mar 26, 2015.

  1. Leandro95

    Leandro95

    Joined:
    Mar 18, 2015
    Posts:
    16
    Hi,
    Thanks for reading. I search a script c# which make an ai of a turret in 2D which follow the position of the player and shoot every x time, if someone can give me a simple code or something else it would be nice
     
  2. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    Here is a script I made a while ago, maybe it can be of some help...
    I had named it LookAt2D, but it does a lot more than just following an object: It can follow, rotate, scan for the closest target (of said tag) and eventually attack.

    I had a more recent version of this script somewhere, where the attack was actually implemented, but unfortunately, I am unable to find it at this moment. This version (copied below) is lacking a few things:
    • Implement the projectile.
    • An Scan Interval so the turret doesn't scan on every frame. (important)
    • if I would redo this today, I would probably use layers instead of tags...

    How it works
    Basically, I'm scanning for the closest target (of said Tag) by using simple Trigonometry.

    How to use?
    1. Copy past the below C# script in a new class. Name it LookAt2D.
    2. Tu use, you need at least 2 GameObjects. (1 for the turret, 1 for the target)
    3. Put this script on the desire Turret.
    4. Give the target (that the turret will seek), a tag.
    5. Put this tag name in the TargetScanner.ScanTag field.
    6. Play around with the different settings
    7. In Playmode, you can test by moving the target around.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class LookAt2D : MonoBehaviour
    5. {
    6.     public Transform target;
    7.     public ScanForTargets targetScanner = new ScanForTargets();
    8.     public RotationTowardsTarget rotateAt = new RotationTowardsTarget();
    9.     public MoveTowardsTarget moveTo = new MoveTowardsTarget();
    10.     public Weapon weapon = new Weapon();
    11.  
    12.     void Update ()
    13.     {
    14.         ScanForTarget();
    15.      
    16.         if(target == null)
    17.             return;
    18.      
    19.         LookAt();
    20.         MoveTorwards();
    21.         Attack();
    22.     }
    23.  
    24.     void ScanForTarget()
    25.     {
    26.         if(!targetScanner.enabled)
    27.             return;
    28.      
    29.         if(Time.time > targetScanner.nextScanInSeconds)
    30.         {
    31.             targetScanner.nextScanInSeconds += targetScanner.scanDelay;
    32.             target = GetNearestTarget();
    33.         }
    34.     }
    35.  
    36.     Transform GetNearestTarget()
    37.     {
    38.         GameObject[] targets = GameObject.FindGameObjectsWithTag(targetScanner.scanTag);
    39.         float nearestDistance = Mathf.Infinity;
    40.         Transform nearestObject = null;
    41.  
    42.         foreach(GameObject obj in targets)
    43.         {
    44.             float distance = FindDistance(transform.position, obj.transform.position);
    45.  
    46.             if(distance < nearestDistance)
    47.             {
    48.                 nearestObject = obj.transform;
    49.                 nearestDistance = distance;
    50.             }
    51.         }
    52.         return nearestObject;
    53.     }
    54.  
    55.     float FindDistance(Vector3 target1, Vector3 target2)
    56.     {
    57.         Vector3 offset = target1 - target2;
    58.         return offset.sqrMagnitude;
    59.     }
    60.  
    61.     void LookAt()
    62.     {
    63.         if(!rotateAt.enabled)
    64.             return;
    65.  
    66.         float distanceX = target.position.x - transform.position.x;
    67.         float distanceY = target.position.y - transform.position.y;
    68.         float angle = Mathf.Atan2(distanceX, distanceY) * Mathf.Rad2Deg;
    69.  
    70.         Quaternion endRotation = Quaternion.AngleAxis(angle, Vector3.back);
    71.         transform.rotation = Quaternion.Slerp(transform.rotation, endRotation, Time.deltaTime * rotateAt.speed);
    72.     }
    73.  
    74.     void MoveTorwards()
    75.     {
    76.         if(!moveTo.enabled)
    77.             return;
    78.  
    79.             transform.position = Vector3.Lerp(transform.position, target.position, moveTo.speed * Time.deltaTime);
    80.     }
    81.  
    82.     void Attack()
    83.     {
    84.         if(!weapon.enabled)
    85.             return;
    86.  
    87.         if (weapon.cooldown > 0)
    88.         {
    89.             weapon.cooldown -= Time.deltaTime;
    90.         }
    91.         else if(weapon.cooldown <= 0)
    92.         {
    93.             print ("ATTACK!");
    94.  
    95.             if(weapon.prefab)
    96.             {
    97.                 //spawn prefab here...
    98.             }
    99.  
    100.             weapon.cooldown = weapon.fireRate;
    101.         }
    102.     }
    103. }
    104.  
    105. [System.Serializable]
    106. public class RotationTowardsTarget
    107. {
    108.     public bool enabled = true;
    109.     public float speed = 5f;
    110. }
    111.  
    112. [System.Serializable]
    113. public class MoveTowardsTarget
    114. {
    115.     public bool enabled = true;
    116.     public float speed = 0.5f;
    117. }
    118.  
    119. [System.Serializable]
    120. public class ScanForTargets
    121. {
    122.     public bool enabled = true;
    123.     public string scanTag;
    124.     public float scanDelay = 0f;
    125.     [System.NonSerialized]
    126.     public float nextScanInSeconds;
    127. }
    128.  
    129. [System.Serializable]
    130. public class Weapon
    131. {
    132.     public bool enabled = true;
    133.     public Transform prefab;
    134.     public float damage = 0f;
    135.     public float fireRate = 1f;
    136.     [System.NonSerialized]
    137.     public float cooldown = 1f;
    138. }
     
    theANMATOR2b likes this.
  3. Leandro95

    Leandro95

    Joined:
    Mar 18, 2015
    Posts:
    16
    Thx i will try it