0

After the enemy collides with the player I want him to stop for some time, so it doesnt chase after him all the time. It looks weird. Like, add an Invoke function or something(not a pro). Please implement it right away (im just a beginner) Here is the code(I was following some 7 hour tutorial):

// Experience
public int xpValue = 1;

//Particle system
public GameObject effect;

// Logic
public float triggerLength = 1;
public float chaseLength = 5;
public bool chasing;
public bool collidingWithPlayer;
private Transform playerTransform;
private Vector3 startingPosition;

// Hitbox
public ContactFilter2D filter;
private BoxCollider2D hitbox;
private Collider2D[] hits = new Collider2D[10];

protected override void Start()
{
    base.Start();
    playerTransform = GameManager.instance.player.transform;
    startingPosition = transform.position;
    hitbox = transform.GetChild(0).GetComponent<BoxCollider2D>();
}

protected void FixedUpdate(){
    //Is the player in range?
    if(Vector3.Distance(playerTransform.position, startingPosition) < chaseLength)
    {
        if(Vector3.Distance(playerTransform.position, startingPosition) < triggerLength)
        chasing = true;

        if (chasing){
            if(!collidingWithPlayer){
                UpdateMotor((playerTransform.position - transform.position).normalized);
            }
        }
        else{
            UpdateMotor(startingPosition - transform.position);
        }
    }
    else{
        UpdateMotor(startingPosition - transform.position);
        chasing = false;
    }

    //Check for overlap
    collidingWithPlayer = false;
    boxCollider.OverlapCollider(filter, hits); // null reference expection
    for (int i = 0; i < hits.Length; i++)
    {
        if (hits[i] == null)\

            continue;

            if(hits[i].tag == "Fighter" && hits[i].name == "Player"){
                collidingWithPlayer = true;
            }

        //this array is not cleaned up, so we do it ourself
        hits[i] = null;
    }
}
Jeff
  • 1
  • 1
  • Why all the protected statements? You dont need to override start. What have you tried to add any formnof delay? – BugFinder Nov 28 '21 at 20:43
  • @BugFinder if there is a common base class which is not `MonoBehaviour` it is not unusual to implement the Unity message methods as `protected virtual` in order to be able to safely `override` them without hiding the base implementation and causing issues where the Unity framework doesn't call the base methods etc – derHugo Nov 29 '21 at 10:31

2 Answers2

1

You will probably want to use either Coroutines or timers to achieve this. This is untested and there is likely some optimization that can be done on this.

Timers

private bool hasAttacked = false;

private float attackTimer = 0;
private float waitTime = 0.5f;

private void Update()
{
   if (!hasAttacked)
   {
      hasAttacked = true;
      attack();
      attackTimer = Time.time + waitTime;
   }
   else
   {
      if ( Time.time > attackTimer)
      {
         hasAttacked = false;
      }
   }
}

This snippet will run an attack function, then wait for 0.5 seconds, and run the code again.

Kyle Posey
  • 45
  • 7
0

Easiest solution would be to look into coroutines. They run on the main thread but can be paused and wait for delays or events.

bool CanAttack()
{
    return true; //Check if can attack here
}

void Attack()
{
    //Put your attacking code here
}

void Start()
{
    StartCoroutine(AttackLoop());
}

IEnumerator AttackLoop()
{
    while (true)
    {
        //Check if enemy can attack
        if (CanAttack())
        {
            Attack();
            //Waits 2 seconds before continuing
            yield return new WaitForSeconds(2f);
        }

        //Wait one frame
        //Prevents an infinite loop
        yield return null;
    }
}
Sean
  • 11
  • 2
  • None of this is working. Can you implement what you weote in my code. Im just a beginner, would appreciate it!!! – Jeff Nov 29 '21 at 11:34