Enemy detect and shoot in player direction when player is in front of it

So far my enemy only shoots when player is to the left of the player but if enemy is patrolling from left to right it means it shoots in opposite direction to player when it moves from right to left and player is still on the left code works fine. if player is to the right and enemy is going right to left it doesn’t shoot which is fine since player is behind enemy.

How do I get enemy to shoot only when player is in front especially at the start.

Here are my codes

Shooting player

using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class ShootingPlayer : MonoBehaviour
{

    //Cached component references
    Animator enemyAnimator;

    //State
    [SerializeField] GameObject enemy;
    [SerializeField] GameObject fireBall;
    [SerializeField] Transform shotSpawnPoint;

    [SerializeField] float timeBetweenShots ;
    [SerializeField] float attackAnimationDuration;

    [SerializeField] float playerRange ;
    [SerializeField] Transform player;

    private float nextShotTime;
    private float endAttackAnimationTime;

    private void Awake()
    {
        enemy = GameObject.Find("Enemy");
        enemyAnimator = enemy.GetComponent<Animator>();
    }

    private void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }

    // Update is called once per frame
    void Update()
    {
        // draws line to detect player at a distance at the start and end of givem range, in this case behind and ahead of enemy
        Debug.DrawLine( new Vector3(transform.position.x + playerRange, transform.position.y, transform.position.z), new Vector3(transform.position.x - playerRange, transform.position.y, transform.position.z));

       
        if (player != null)
        {
            ShootAtPlayer();
        }

      
        if (enemyAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Attacking") && Time.time > endAttackAnimationTime)
        {
            enemyAnimator.SetBool("Attacking", false);
        }
    }

    public void ShootAtPlayer()
    {

        if (transform.localScale.x > 0 && player.transform.position.x < transform.position.x && player.transform.position.x > transform.position.x - playerRange && Time.time > nextShotTime)
        {
            Debug.Log("fireball going right");
            Instantiate(fireBall, shotSpawnPoint.position, shotSpawnPoint.rotation);
            enemyAnimator.SetBool("Attacking", true);
            nextShotTime = Time.time + timeBetweenShots;
            endAttackAnimationTime = Time.time + attackAnimationDuration;
        }

        // somehow never enters this loop

        if (transform.localScale.x < 0 && player.transform.position.x > transform.position.x && player.transform.position.x < transform.position.x + playerRange && Time.time > nextShotTime)
        {
            Debug.Log("fireball going left");
            Instantiate(fireBall, shotSpawnPoint.position, shotSpawnPoint.rotation);
            enemyAnimator.SetBool("Attacking", true);
            nextShotTime = Time.time + timeBetweenShots;
            endAttackAnimationTime = Time.time + attackAnimationDuration;
        }

        /* Continuous attacking

       if (Time.time > nextShotTime)
       {
           Instantiate(fireBall, shotSpawnPoint.position, shotSpawnPoint.rotation);
           enemyAnimator.SetBool("Attacking", true);
           nextShotTime = Time.time + timeBetweenShots;
           endAttackAnimationTime = Time.time + attackAnimationDuration;
       }
       */


    }
}

Fireball

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fireball : MonoBehaviour
{
    public float speed;
    public int damage;
    public float lifeTime;
    private GameObject player;

    // Start is called before the first frame update
    void Start()
    {
       
        //delay , basically to define, after how many seconds would we like to destroy game object
        Destroy(gameObject, lifeTime);
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(Vector2.left * speed * Time.deltaTime);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            collision.GetComponent<Player>().TakeDamage(damage);
        }
        Destroy(gameObject);
    }
}

patrol

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Patrol : MonoBehaviour
{
    public float speed;
    public float distance;
   

    private bool movingRight = true;

    public Transform groundDetection;
   

    private void Update()
    {
        transform.Translate(Vector2.right * speed * Time.deltaTime);
        int layer_mask = LayerMask.GetMask("Ground");
      
        RaycastHit2D groundinfo = Physics2D.Raycast(groundDetection.position, Vector2.down, distance, layer_mask); //origin, direction, distance
      

        if (groundinfo.collider == false)
        {
            if(movingRight == true)
            {
                transform.eulerAngles = new Vector3(0, -180, 0); //turn 180 degrees
                movingRight = false;
            }
            else
            {
                transform.eulerAngles = new Vector3(0, 0, 0);
                movingRight = true;
            }
        }
    }


}

You need to make it so the enemy only shoots when the player is in the raycast. When the enemy turns or “flips”, the raycast should still face the same direction as the enemy.

As for the projectile, you are using Vector2.left so it will always shoot left, even if you fix your raycast issue. Try using Vector2.forward or something like that.

This is something i used in the past for a projectile that takes the player’s X and Y position (aka it can shoot in different angles, not just horizontally.

moveDirection = (target.transform.position - transform.position).normalized* moveSpeed;
rb.velocity = new Vector2(moveDirection.x, moveDirection.y);

I’m not terribly familiar with Raycasts could you please tell me what I should change for that to occur the way you mentioned. I’m an absolute beginner.

as for the target position… I’d need to take in the player as a transform and for some reason unity isn’t letting me since the fireball script is on the prefab. which isn’t actually in the scene. would you know what I could do as a workaround or if I’m calling the player wrong ?

Try this quick video for raycasts. You actually already use one in your Patrol script on line 21. Basically, it shoots a ray out that records collisions. You can determine what collisions to detect, how long the ray goes and more. You can also use the Debug.DrawRay() function to show the ray while testing.

You can grab the player’s position when the fireball is instantiated.

    Player target;
    Vector2 moveDirection;


    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        target = FindObjectOfType<Player>();
    }
    // Use this for initialization
    void Start ()
    {     
        moveDirection = (target.transform.position - transform.position).normalized* moveSpeed;
        rb.velocity = new Vector2(moveDirection.x, moveDirection.y);
    }