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). Would appreciate your help) 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;
}
}
CodePudding user response:
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.
CodePudding user response:
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() => true;
void Attack() { }
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;
//Some other Examples
//Wait until true
yield return new WaitUntil(CanAttack);
//Wait until false
yield return new WaitWhile(CanAttack);
}
}