archer xd

mail@pastecode.io avatar
unknown
csharp
15 days ago
6.7 kB
2
Indexable
Never
using System.Collections;
using TMPro;
using UnityEngine;

public class ArcherEnemy : Enemy
{
    public GameObject stompArea;
    public GameObject floatingTextPrefab;

    public LayerMask playerLayer;

    [Header("Shooting")]
    public GameObject arrowPrefab;
    public Transform firePoint;
    public float timeBetweenShots = 2f;
    public float cooldownTimeforshootingArrow;
    public float detectionRange;

    [Header("Alert")]
    public GameObject alertSign;
    private bool isShowingAlertSign = false;
    private bool hasShownAlertSign = false;

    private CapsuleCollider2D capsuleCollider2D;
    private SpriteRenderer spriteRenderer;
    private Rigidbody2D theRB;
    private SpriteRenderer theSR;

    [Header("Knockback")]
    public float knockBackForceX = 5f;
    public float knockBackForceY = 2f;
    public float knockBackDuration = 0.5f;

    [Header("Attack")]
    private bool playerDetected;
    private bool canShootArrow = true;
    private Transform playerTransform;
    public float attackCooldownTimer;
    private bool movingRight;

    void Start()
    {
        capsuleCollider2D = GetComponent<CapsuleCollider2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
        theRB = GetComponent<Rigidbody2D>();
        theSR = GetComponent<SpriteRenderer>();

        playerDetected = false;

        StartCoroutine(ChangeDirectionRoutine());


    }


    void Update()
    {
        DetectPlayer();

        if (playerDetected && attackCooldownTimer <= 0f)
        {
            StartCoroutine(ShootArrowRoutine());
        }

        
        attackCooldownTimer -= Time.deltaTime;
    }



    void DetectPlayer()
    {
        Vector2 direction = movingRight ? Vector2.right : Vector2.left;
        RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, detectionRange, playerLayer);

        Debug.DrawRay(transform.position, direction * detectionRange, Color.red);

        if (hit.collider != null && hit.collider.CompareTag("Player"))
        {
            playerDetected = true;
            playerTransform = hit.collider.transform;

            if (!isShowingAlertSign && !hasShownAlertSign)
            {
                StartCoroutine(ShowAndHideSignCoroutine());
            }
        }
        else
        {
            playerDetected = false;
            playerTransform = null;
        }
    }

    private IEnumerator ShootArrowRoutine()
    {

        if (playerDetected && canShootArrow == true)
        {

            new WaitForSeconds(cooldownTimeforshootingArrow);
         
            anim.SetTrigger("Attack");
            yield return new WaitForSeconds(0.5f); // Wait for the animation to reach the shooting point

            
            float flipFactor = theSR.flipX ? -1f : 1f;

            // Instantiate the arrow and set its velocity based on the archer's facing direction
            GameObject arrow = Instantiate(arrowPrefab, firePoint.position, Quaternion.identity);
            canShootArrow = false;


            yield return TimeBetweenShoots();
            canShootArrow = true;
        }
        else
        {
            yield return null; // Wait for the next frame and check again
        }

    }


    private IEnumerator ShowAndHideSignCoroutine()
    {
        isShowingAlertSign = true;
        alertSign.SetActive(true);

        yield return new WaitForSeconds(1f);

        alertSign.SetActive(false);
        isShowingAlertSign = false;
        hasShownAlertSign = true;
    }

    public void ResetAlertSign()
    {
        hasShownAlertSign = false;
    }

    private IEnumerator ChangeDirectionRoutine()
    {
        while (true)
        {
            yield return new WaitForSeconds(Random.Range(2f, 5f));
            if (!playerDetected) // Ensure the player is not detected before flipping
            {
                theSR.flipX = !theSR.flipX;
                movingRight = !movingRight;
            }
        }

    }

    private IEnumerator TimeBetweenShoots()
    {
        if (canShootArrow == false)
        {
            new WaitForSeconds(timeBetweenShots);
        }
        else
        {
            yield break;
        }
    }







    public void Squashed()
    {
        health = 0;
        alertSign.SetActive(false);
        hasShownAlertSign = true;
        rb.bodyType = RigidbodyType2D.Kinematic;
        stompArea.SetActive(false);
        anim.SetTrigger("Squashed");
        capsuleCollider2D.enabled = false;
        //deadZone.enabled = false;
        PointsController.instance.MaleeBanditPoints();
        if (floatingTextPrefab != null)
        {
            GameObject floatingText = Instantiate(floatingTextPrefab, transform.position, Quaternion.identity);
            floatingText.GetComponentInChildren<TextMeshProUGUI>().text = "100";
        }

        StartCoroutine(FadeOutCoroutine(6));
    }

    private IEnumerator FadeOutCoroutine(float duration)
    {
        Color color = spriteRenderer.color;
        float startAlpha = color.a;
        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            elapsedTime += Time.deltaTime;
            float newAlpha = Mathf.Lerp(startAlpha, 0f, elapsedTime / duration);
            spriteRenderer.color = new Color(color.r, color.g, color.b, newAlpha);
            yield return null;
        }

        spriteRenderer.color = new Color(color.r, color.g, color.b, 0f);
    }

    public override void HurtSequence()
    {
        anim.SetTrigger("Hit");
        FlipDirection();
        //UpdateAttackZones();
    }

    private void FlipDirection()
    {
        if (playerTransform == null) // Flip only if enemy is not facing the Player
        {
            theSR.flipX = !theSR.flipX;
            movingRight = !movingRight;
            //UpdateAttackZones();
        }
    }

    public override void DeathSequence()
    {
        hasShownAlertSign = true;
        alertSign.SetActive(false);
        anim.SetTrigger("Death");
        anim.ResetTrigger("isMoving");
        anim.ResetTrigger("Attack");
        rb.bodyType = RigidbodyType2D.Kinematic;
        capsuleCollider2D.enabled = false;
        stompArea.SetActive(false);
        //attackDetectionZone.enabled = false;
        //deadZone.enabled = false;
        rb.gravityScale = 0;
        PointsController.instance.MaleeBanditPoints();

        if (floatingTextPrefab != null)
        {
            GameObject floatingText = Instantiate(floatingTextPrefab, transform.position, Quaternion.identity);
            floatingText.GetComponentInChildren<TextMeshProUGUI>().text = "100";
        }

        StartCoroutine(FadeOutCoroutine(6));
    }
Leave a Comment