AI Attack script for enemy spacecraft.

Hi All

I am just new to Unity and Scripting but I have been using a lot of tutorials to get the basics and I am currently trying my hand at a space RTS, I have got most of the basics, resources, unit and structure building, basic click to move (I struggled with this for a while trying to figure out movement in 3D space). So I would say I am progressing very slowly, an RTS seem to be a much more complex beast than an FPS or RPG to create :-).

I am struggling on AI attack behaviors for my ships.

This is what I have so far.

using UnityEngine;
using System.Collections;

public class AttackAi : MonoBehaviour {
    float moveSpeed = 50f;
    float randomx;
    float randomy;
    float randomz;
    float distance;
    float distanceT;
    int switchTarget;
    public bool AITarget;
    public bool randomTarget;
    // Use this for initialization
    public Transform enemyTarget;
    Transform newTarget;
    Vector3 destinationPosition;

    void Start () {
        destinationPosition = enemyTarget.position ;
        switchTarget = 0;
         AITarget = true;
        randomTarget = false;
    }
   
    // Update is called once per frame
    void FixedUpdate () {
        randomx = Random .Range (-500, 500);
        randomy = Random .Range (-500, 500);
        randomz = Random .Range (-500, 500);
        if (AITarget == true) {
            distance = Vector3 .Distance (transform .position, enemyTarget .position);
        }else
         {
            distanceT = Vector3 .Distance (transform .position, destinationPosition);
            Debug.Log (distanceT );
        }

        switch (switchTarget) {
        case 1:

            Vector3 positionx = new Vector3 (enemyTarget .position .x+randomx, enemyTarget .position .y, enemyTarget .position .z);
            destinationPosition = positionx;
            switchTarget = 0;
            break;
           
        case 2:
            Vector3 positiony = new Vector3 (enemyTarget .position .x, enemyTarget .position .y+randomy, enemyTarget .position .z);
            destinationPosition = positiony;
            switchTarget = 0;
            break;

        case 3:
            Vector3 positionz = new Vector3 (enemyTarget .position .x, enemyTarget .position .y, enemyTarget .position .z+randomz);
            destinationPosition = positionz;
            switchTarget = 0;
            break;
        }

if (distance    < 300 && AITarget == true)
            {
            switchTarget = Random .Range (1,3);
            AITarget = false;
            randomTarget = true;

            }
        else if (distanceT    < 50 && randomTarget == true)
        {

            destinationPosition = enemyTarget.position ;
            AITarget = true;
            randomTarget = false;
           
        }
        Quaternion  targetRotation = Quaternion.LookRotation (destinationPosition  - transform.position);
        transform.rotation = Quaternion .Slerp (transform .rotation, targetRotation , Time.deltaTime);
        transform.position = Vector3.MoveTowards (transform.position, destinationPosition , moveSpeed * Time.deltaTime);

    }
}

Now this code does work but not very good, it works OK I guess for a fighter attacking a slow moving capital ship, but for fighter v fighter its just useless. Also as this is based on the transform position of the enemy, it doesnt take into consideration the mesh extents of the ship so sometimes my ships go through the object rather than avoid it.

The main issues with my script is there is no smooth angle of change towards the random target, the random isnt giving me the best effect for a strafing run and at the moment my ships have no real yaw or pitch.

So looking for some help to refine and improve upon my script, to give my AI some life to them, this script is for fighters or fast moving ships only, I am currently working on a capital ship script which uses more of a RotateAround so it can broadside with its weapons.

Cheers

Druid

For movement, I’d suggest steering behaviours (there are a lot of tutorials, just google for them). They are very suitable for space and look good. Basic idea of them is mixing forces to get resulting force, then apply it.

For rotation, Either fixed angular speed or angular forces. The way you do Slerp you will slow down rotating linearly, while you would want to have either fixed rotation for simple case or using acceleration(=forces as F=ma) for real-like rotation which starts with acceleration and ends with deceleration.
In case of fixed, you can remember first rotation, destination rotation and slerp between them depending on rotational speed. In case of forces you’d need to write two parts: acceleration and deceleration, you could use something like steering behaviours for that (I mean mixing forces in order to get resulting one).

As for even better looks after, you’d need A.I. to become more complex like moving on to “bomb”, evading, maneuvering (your fighter wants to get into enemy tail while not letting enemy get in tail), etc.

I’m messing around with a similar issue. I’ve been researching it for about a week. I knew I’d want PID error correction. PID itself is very simple, but for deciding how to setup the error inputs, I kept coming back to the sample project below. It is 2D and stationary but illustrates the control concept quite well. My partially-working 3D solution was posted last night at the end of the thread:

There are questions about this very thing going back many years, and what you’ll find is the experienced guys recommend against a real-physics approach for game purposes. In a nutshell, there seems to be consensus that fake physics makes for a better player experience. (However, in my case I’m not really doing a game so I’m forging ahead.)

Once you start searching the forums and unity answers for PID topics you’ll find tons and tons of material – but it’s still difficult.