Strahinja Eric
Strahinja Eric

Reputation: 1

Unity 2D Enemy Behavior (Couple of Questions)

I need help with making my Enemy stop moving once the Player is in range. When a Player enters the range of the Enemy, the Enemy will start moving towards the Player, and won't stop until the Player is pushed off the cliff. Also the Enemy doesn't seem to play the Attack animation once it reaches the Player. I will put my code down below:

#region Public Variables
 public Transform rayCast;
 public LayerMask raycastMask;
 public float rayCastLength;
 public float attackDistance; //Minimum distance for attack
 public float moveSpeed = 4f;
 public float timer; //Timer for cooldown between attacks
#endregion

#region Private Variables
 private RaycastHit2D hit;
 private GameObject target;
 private Animator anim;
 private float distance;//Store the distance between enemy and player
 private bool attackMode;
 private bool inRange; //Check if Player is in range
 private bool cooling; //Check if Enemy is cooling after attack
 private float intTimer;
#endregion

void Awake ()
{
    intTimer = timer; //Store the initial value of timer
    anim = GetComponent<Animator>();
}

void Update()
{
    if (inRange)
    {
        hit = Physics2D.Raycast(rayCast.position, Vector2.left,rayCastLength, raycastMask);
        RaycastDebugger();
    }
    
    //When Player is detected
    if(hit.collider != null)
    {
        EnemyLogic();
    }
    else if(hit.collider == null)
    {
        inRange = false;
    }

    if (inRange == false)
    {
        anim.SetBool("canWalk", false);
        StopAttack();
    }
}

void OnTriggerEnter2D(Collider2D trig)
{
    if(trig.gameObject.tag == "Player")
    {
        target = trig.gameObject;
        inRange = true;
    }
}

void EnemyLogic ()
{
    distance = Vector2.Distance(transform.position, target.transform.position);
    if(distance > attackDistance)
    {
        Move();
        StopAttack();
    }
    else if(attackDistance >= distance && cooling == false)
    {
        Attack();
    }
    if(cooling)
    {
        Cooldown();
        anim.SetBool("Attack", false);
    }
}

void Move()
{
    anim.SetBool("canWalk", true);
    if(!anim.GetCurrentAnimatorStateInfo(0).IsName("Goblin Attack"))
    {
        Vector2 targetPosition = new Vector2(target.transform.position.x, transform.position.y);
        transform.position = Vector2.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
    }
}

void Attack()
{
    timer = intTimer; //Reset Timer when Player enter Attack Range
    attackMode = true; //To check if Enemy can still attack or not

    anim.SetBool("canWalk", false);
    anim.SetBool("Attack", true);
}

void Cooldown ()
{
    timer -= Time.deltaTime;

    if(timer <= 0 && cooling && attackMode)
    {
        cooling = false;
        timer = intTimer;
    }
}

void StopAttack()
{
    cooling = false;
    attackMode = false;
    anim.SetBool("Attack", false);
}

void RaycastDebugger()
{
    if(distance > attackDistance)
    {
        Debug.DrawRay(rayCast.position, Vector2.left * rayCastLength, Color.red);
    }
    else if(attackDistance > distance)
    {
        Debug.DrawRay(rayCast.position, Vector2.left * rayCastLength, Color.green);
    }
}

public void TriggerCooling ()
{
    cooling = true;
}

Upvotes: 0

Views: 159

Answers (1)

Toash
Toash

Reputation: 15

it seems that you are not setting

private RaycastHit2D hit;

to null, yet you are checking if it is null,

else if(hit.collider == null)

which could explain why the enemy keeps chasing the player.

Also in the raycast there is no way to differentiate for the player.

//When Player is detected if(hit.collider != null)

You are checking if player is detected, but hit could be anything other than the player.

hit = Physics2D.Raycast(rayCast.position, Vector2.left,rayCastLength, raycastMask);

So the ray could collide with the floor or something and not see the player, but in the enemies eyes they saw the player. Or maybe you are passing in a player layermask? In that case renaming the "raycastMask" to something like playerMask would make it more readable.

Upvotes: 1

Related Questions