- Home /
i need help with make an attack animation only when the player is near
//right now its stuck looping the attack animation at all times i cant tell if its a coding problem exactly or a animator controller set up problem help if possible.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;
public class EnemyAttack : MonoBehaviour { public float timeBetweenAttacks = 0.5f; public int attackDamage = 10;
Animator anim;
GameObject player;
PlayerHealth playerHealth;
//EnemyHealth enemyHealth;
bool playerInRange;
float timer;
// Use this for initialization
void Awake ()
{
player = GameObject.FindGameObjectWithTag("Player");
playerHealth = player.GetComponent<PlayerHealth> ();
//enemyHealth = GetComponent<EnemyHealth> ();
anim = GetComponent <Animator> ();
}
// Update is called once per frame
void OnTriggerEnter (Collider other)
{
if(other.gameObject == player)
{
playerInRange = true;
anim.SetTrigger("Attack");
}
}
void OnTriggerExit(Collider other)
{
if(other.gameObject == player)
{
playerInRange = false;
}
}
void Update()
{
timer += Time.deltaTime;
if (timer >= timeBetweenAttacks && playerInRange/* && enemyHealth.currentHealth > 0*/)
{
Attack();
}
if (playerHealth.currentHealth <= 0)
{
Destroy(player);
}
}
void Attack()
{
timer = 0f;
if(playerHealth.currentHealth > 0)
{
playerHealth.TakeDamage(attackDamage);
}
}
}
Can you try to use anim.ResetTrigger()
once the player is out of range?
Answer by Kciwsolb · Apr 18, 2018 at 04:23 PM
You have a few issues here. For one, when you set your timer plus equal to Time.deltaTime, you are setting it to the time it took to render the last frame. This might be causing the constant attacking. Also, you may want to call an Attack method in OnTriggerStay(Collider other) if other.gameObject is the player. By doing this, it will be (for the most part) called every frame that the player is touching the enemy trigger. You don't really need a bool for playerInRange that way.
private void Attack() //Call this in OnTriggerStay if the colliding gameObject is the player
{
if(Time.time >= timer) //Check if current game time is at or past the time we last set
{
playerHealth.TakeDamage(attackDamage); //make player take damage
animator.SetTrigger("Attack"); //trigger our animation
timer = Time.time + attackDelay; //Set timer to current game time plus our delay
}
}
Important!! Be sure in your AnimatorController there is a transition from your attack animation back to your idle animation. And be sure your attack animation clip does not have loop time set. Since you are triggering the animation, you only want it to play once until we trigger it again. So make sure it just transitions back to idle when it finishes.
Hope this helps get you going in the right direction.
Also, personally I would have the PlayerHealth script check if the currentHealth is
So you might have a TakeDamage method on PlayerHealth something like this:
public void TakeDamage(int attackDamage)
{
currentHealth -= attackDamage;
if(currentHealth <= 0)
{
Destroy(gameObject);
}
}