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

Question AI Jet roaming and navigation

Discussion in 'Scripting' started by W_d_gaster_, Dec 23, 2022.

  1. W_d_gaster_

    W_d_gaster_

    Joined:
    Oct 21, 2022
    Posts:
    2
    So I'm trying to get this AI Jet to fly a similar way to how the player jet flies. I'm aiming more for a simple simulation flight kind of like GTA 5 and not something overly realistic. My aim is to have it roam around the skies and once the player jet is in range it will attempt to intercept the player jet. I'm just unsure how to get the jet to move forward and yaw, pitch and roll on it's own with no input from the player. The code I // is what would allow me to control the AI jet, I hashed it out so I have no control over the AI.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. [RequireComponent(typeof(Rigidbody))]
    7. public class AIControls : MonoBehaviour
    8. {
    9.     public Transform target;
    10.     public Transform jetMesh;
    11.  
    12.     public float EngineThrust = 35000f;
    13.     public float PitchSpeed = 60f;
    14.     public float RollSpeed = 200f;
    15.     public float YawSpeed = 60f;
    16.     public float autoTurnAngle = 30f;
    17.  
    18.     private Rigidbody rb;
    19.  
    20.     private float Thrust;
    21.     private float Pitch;
    22.     private float Roll;
    23.     private float Yaw;
    24.     private float LateralWanderDistance;
    25.     private float LateralWanderSpeed;
    26.     private float RandomPerlin;
    27.  
    28.     internal float Speed;
    29.     internal float Altitude;
    30.     internal float Throttle { get { return Thrust; } }
    31.  
    32.     private const float mToKm = 4f;
    33.     private const float kmToKnots = 0.6f;
    34.     private const float aerodynamicEffect = 0.1f;
    35.  
    36.     void start()
    37.     {
    38.         target = GameObject.FindGameObjectWithTag("Player").transform;
    39.         rb = GetComponent<Rigidbody>();
    40.     }
    41.  
    42.     private void Awake()
    43.     {
    44.         rb = GetComponent<Rigidbody>();
    45.         if (rb == null) rb = gameObject.AddComponent<Rigidbody>();
    46.  
    47.         if (rb.mass == 1)
    48.         {
    49.             rb.mass = 20000;
    50.             rb.drag = 0.075f;
    51.             rb.angularDrag = 0.05f;
    52.         }
    53.  
    54.         // pick a random perlin starting point for lateral wandering
    55.         RandomPerlin = Random.Range(0f, 100f);
    56.     }
    57.  
    58.     void Update()
    59.     {
    60.       //Clear old values
    61.         Pitch = 0f;
    62.         Roll = 0f;
    63.         Yaw = 0f;
    64.  
    65.         //Updating controls
    66.         //if (Input.GetKey(KeyCode.Q)) Yaw = -1f;
    67.         //if (Input.GetKey(KeyCode.E)) Yaw = 1f;
    68.  
    69.         //if (Input.GetKey(KeyCode.A)) Roll = 1f;
    70.         //if (Input.GetKey(KeyCode.D)) Roll = -1f;
    71.  
    72.         //if (Input.GetKey(KeyCode.W)) Pitch = 1f;
    73.         //if (Input.GetKey(KeyCode.S)) Pitch = -1f;
    74.  
    75.         UpdateThrottle();
    76.     }
    77.  
    78.     void UpdateThrottle()
    79.     {
    80.         //if (Input.GetKeyDown(KeyCode.O)) Thrust = 30f;
    81.         //if (Input.GetKeyDown(KeyCode.P)) Thrust = 60f;
    82.         //if (Input.GetKeyDown(KeyCode.Backspace)) Thrust = 100f;
    83.         //if (Input.GetKeyDown(KeyCode.Backslash)) Thrust = 0f;
    84.  
    85.         //if (Input.GetKeyDown(KeyCode.KeypadPlus)) Thrust += 10f;
    86.         //if (Input.GetKeyDown(KeyCode.KeypadMinus)) Thrust -= -10f;
    87.  
    88.         Thrust = Mathf.Clamp(Thrust, 0f, 100f);
    89.     }
    90.  
    91.     void Controls()
    92.     {
    93.         var dir = (target.position - transform.position).normalized;
    94.         var localTarget = transform.InverseTransformDirection(dir).normalized * 5f;
    95.         var targetRollAngle = Mathf.Lerp(0f, autoTurnAngle, Mathf.Abs(localTarget.x));
    96.         if (localTarget.x > 0f) targetRollAngle *= -1f;
    97.  
    98.         var rollAngle = FindAngle(jetMesh.transform.localEulerAngles.z);
    99.         var newAngle = targetRollAngle - rollAngle;
    100.  
    101.         Pitch = -Mathf.Clamp(localTarget.y, -1f, 1f);
    102.         Roll = Mathf.Clamp(newAngle, -1f, 1f);
    103.         Yaw = Mathf.Clamp(localTarget.x, -1f, 1f);
    104.     }
    105.  
    106.     float FindAngle(float v)
    107.     {
    108.         if (v > 180f) v -= 360f;
    109.         return v;
    110.     }
    111.  
    112.     private void FixedUpdate()
    113.     {
    114.  
    115.         if (target != null)
    116.         {
    117.             // make the plane wander from the path, useful for making the AI seem more human, less robotic.
    118.             Vector3 targetPos = target.position +
    119.                                 transform.right*
    120.                                 (Mathf.PerlinNoise(Time.time * LateralWanderSpeed, RandomPerlin)*2 - 1)*
    121.                                 LateralWanderDistance;
    122.         }
    123.  
    124.         transform.RotateAround(transform.position, transform.up, Yaw * Time.fixedDeltaTime * YawSpeed);
    125.         if (Altitude > 20f)
    126.             jetMesh.transform.RotateAround(jetMesh.transform.position, jetMesh.transform.forward, Roll * Time.fixedDeltaTime * RollSpeed);
    127.         //if (rb.velocity.magnitude > 100f)
    128.             transform.RotateAround(transform.position, transform.right, Pitch * Time.fixedDeltaTime * PitchSpeed);
    129.      
    130.         var localVelocity = transform.InverseTransformDirection(rb.velocity);
    131.         var localSpeed = Mathf.Max(0, localVelocity.z);
    132.         Speed = (localSpeed * mToKm) * kmToKnots;
    133.  
    134.         //Borrowed from Unity Standard Assets
    135.         var aerofactor = Vector3.Dot(transform.forward, rb.velocity.normalized);
    136.         aerofactor *= aerofactor;
    137.         rb.velocity = Vector3.Lerp(rb.velocity, transform.forward * localSpeed, aerofactor * localSpeed * aerodynamicEffect * Time.fixedDeltaTime);
    138.  
    139.         if (Speed < 4000)
    140.             {
    141.                 rb.AddForce((Thrust * EngineThrust) * transform.forward);
    142.             }
    143.      
    144.     }
    145. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,957
    From a top-down view my MissileTurnTowards game will home into a target.

    It does not address altitude, and it also does not address the issue of an unreachable target that is too close to reach and you end up orbiting. You can address this either by slowing down the jet, or else by inhibiting turning for a short time to allow the jet to get away for a distance, then come back afresh.

    The simple package is attached. I put it in my Kurt Arcade package and implemented anti-orbiting mentioned above.

    Appstore: https://apps.apple.com/ch/app/kurt-arcade/id1591748111
    Google Play: https://play.google.com/store/apps/details?id=com.kurt.arcadetv

    Screenshot-arcade-133163713343268490.png
     

    Attached Files:

  3. W_d_gaster_

    W_d_gaster_

    Joined:
    Oct 21, 2022
    Posts:
    2
    Oh okay I see, thank you for that. I'll check it out when get the chance and will give it a try. Thank you