'trying to make an enemy shoot a projectile at the player when the player enters the enemys range

for some reason the projectile is fired but only when the enemy comes into contact with the player and very slowly for some reason. below is my code.

(there is a separate script on my projectile but that only deals with damage on the player)

public class flyingEnemy : MonoBehaviour {


    public int maxHealth = 40;
    Rigidbody2D rb2d;

    public float speed;



    public float attackRange;
    private float lastAttackTime;
    public float attackDelay;

    public Transform target;
    public float chaseRange;

    public GameObject projectile;
    public float bulletForce;
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        float distanceToTarget = Vector3.Distance(transform.position, target.position);
        if(distanceToTarget < chaseRange)
        {
            //start chasing player
            Vector3 targetDir = target.position - transform.position;
            float angle = Mathf.Atan2(targetDir.y, targetDir.x) * Mathf.Rad2Deg - 90f;
            Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 180);

            transform.Translate(Vector3.up * Time.deltaTime * speed);

        }
        if(distanceToTarget < attackRange)
        {

            //check to see if its time to attack again
            if (Time.time > lastAttackTime + attackDelay)
            {
                //do we have lineofsight?
                RaycastHit2D Hit = Physics2D.Raycast(transform.position, transform.up,attackRange);
                //what did the raycast hit?
                if (Hit.transform == target)
                {
                    GameObject newBullet = Instantiate(projectile, transform.position, transform.rotation);
                    newBullet.GetComponent<Rigidbody2D>().AddRelativeForce(new Vector2(0f, bulletForce));
                    lastAttackTime = Time.time;
                }
            }
        }


    }


Solution 1:[1]

I modified your code and it seems to work now. I added a 'Player' layer to the player gameobject, then rewrote your script to the following:

using UnityEngine;

public class Enemy : MonoBehaviour
{

public int maxHealth = 40;

public float speed;
public float attackRange;
public float attackDelay;
public float chaseRange;
public float bulletForce;
private float lastAttackTime;
private float distanceToTarget;

public Transform target;
public GameObject projectile;
private Rigidbody2D rb2d;

private void Start()
{
    rb2d = GetComponent<Rigidbody2D>();
}

private void FixedUpdate()
{
    if (distanceToTarget < chaseRange)
    {
        Chase(target.position);
    }
    else
    {
        rb2d.velocity = Vector2.zero;
    }
}

private void Update()
{
    distanceToTarget = Vector3.Distance(transform.position, target.position);

    if (distanceToTarget < attackRange)
    {
        if (Time.time > lastAttackTime + attackDelay)
        {
            RaycastHit2D Hit = Physics2D.Raycast(transform.position, transform.up, attackRange, 1 << LayerMask.NameToLayer("Player"));
            if (Hit)
            {
                Fire();
                lastAttackTime = Time.time;
            }
        }
    }
}

private void Chase(Vector3 target)
{
    Vector3 targetDir = target - transform.position;
    float angle = Mathf.Atan2(targetDir.y, targetDir.x) * Mathf.Rad2Deg - 90f;
    Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
    transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 180);
    rb2d.velocity = targetDir.normalized * speed;
}

private void Fire()
{
    GameObject newBullet = Instantiate(projectile, transform.position, transform.rotation);
    newBullet.GetComponent<Rigidbody2D>().AddForce(transform.up * bulletForce, ForceMode2D.Impulse);
}    
}

First, if you have a rigidbody, use that instead of Transform.Translate. Second, make sure your raycast only applies to the Player layer. Third, rather than

AddRelativeForce(new Vector2(0f, bulletForce));

use

AddForce(transform.up * bulletForce, ForceMode2D.Impulse);

Fourth, play around with the serialized values until you get the result you want. What I did was lower the enemy's speed and increase the bullet force. Let me know if you have any questions.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1