Fix player attack at specific animartion frame

Hi guys, i would like some help if possible. Right now im prototype a top down isometric click to move game and i already have this 3 scripts, everything works fine, player move with mouse click, attack enemy, enemy chase and attack player. The onyl thing here is i want the player only damage the enemy in a specif frame of attack animation, and right know it doesnt happen. Can anyone tell how can i do that? Im using mecanim and trigger parameter in animator to activate the animation. Appreciate

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class NPCBehavior : MonoBehaviour
{
    //variables
    protected Vector3 targetToWalk;
    protected NavMeshAgent agent;

    //stats
    public float MaxHp;
    private float currentHp;
    public int attackPower;
    public int armor;
    public float attackRate;
    private float currentAttackRate;
    public float attackRange;
    public float hpRegen;

    //UI
    public GameObject lifeBarPrefab;
    public Transform lifeBarPosition;
    private Slider lifeBar;

    protected Animator anim;

    // Use this for initialization
    virtual protected void Start () {
        agent = GetComponent<NavMeshAgent>();
        targetToWalk = transform.position;
        currentHp = MaxHp;

        anim = GetComponentInChildren<Animator>();

        //life bar
        GameObject tempLifeBar = Instantiate(lifeBarPrefab, lifeBarPosition.position, transform.rotation) as GameObject;
        tempLifeBar.transform.SetParent (lifeBarPosition, true);
        lifeBar = tempLifeBar.GetComponentInChildren<Slider> ();
        lifeBar.maxValue = MaxHp;
    }
   
    // Update is called once per frame
    virtual protected void Update () {

        //animations
        if (anim != null) {
            anim.SetFloat ("velocity", agent.velocity.magnitude);
        }
       
        lifeBar.value = currentHp;

        //lifeBarPosition.LookAt (Camera.main.transform);

        if (targetToWalk != transform.position) {
            agent.SetDestination (targetToWalk);
        }

        if (currentAttackRate < attackRate) {
            currentAttackRate += Time.deltaTime;
        }
    }

    public void Attack(NPCBehavior target){
        if (CanAttack ()) {
            target.ApplyDamage (attackPower);
            currentAttackRate = 0;

            if (anim != null) {
                anim.SetTrigger ("attack");
            }
        }
    }

    public bool CanAttack(){
        return currentAttackRate >= attackRate;
    }

    public void ApplyDamage(float damage){
        if (damage > armor) {
            currentHp -= damage;

            if (currentHp <= 0) {
                Die ();
            }

            if (anim != null) {
                anim.SetTrigger ("hit");
            }
        }
    }

    public void Die(){
        Destroy (gameObject);
    }
}
using UnityEngine;
using System.Collections;

public class PlayerController : NPCBehavior
{
    private EnemyBehavior enemyTarget;

    // Use this for initialization
    void Start ()
    {
        base.Start ();
    }
   
    // Update is called once per frame
    void Update ()
    {
        base.Update ();

        if (Input.GetMouseButtonDown (0)) {
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast (ray, out hit)) {
                targetToWalk = hit.point;

                if (hit.collider.GetComponent<EnemyBehavior> ()) {
                    enemyTarget = hit.collider.GetComponent<EnemyBehavior> ();
                }
                else {
                    enemyTarget = null;
                }
            }               
        }

        if (enemyTarget != null) {
            if (Vector3.Distance (enemyTarget.transform.position, transform.position) <= attackRange) {
                Attack (enemyTarget);
            }

            agent.stoppingDistance = attackRange;
            targetToWalk = enemyTarget.transform.position;
        }
        else {
            agent.stoppingDistance = 0;
        }
    }
}
using UnityEngine;
using System.Collections;

public class EnemyBehavior : NPCBehavior
{
    public bool isAgressive;
    public float distanceToFollow;
    public float distanceToGoBackStartPosition;

    private float currentDistanceToPlayer;
    private float currentDistanceToGoBack;
    private PlayerController player;
    private Vector3 startPosition;

    // Use this for initialization
    void Start () {
        base.Start ();
        player = FindObjectOfType (typeof(PlayerController)) as PlayerController;
        startPosition = transform.position;
    }
   
    // Update is called once per frame
    void Update () {
        base.Update ();

        currentDistanceToPlayer = Vector3.Distance (player.transform.position, transform.position);
        currentDistanceToGoBack = Vector3.Distance (startPosition, transform.position);

        if (currentDistanceToGoBack >= distanceToGoBackStartPosition) {
            targetToWalk = startPosition;
        }
        else {
            if (isAgressive && currentDistanceToPlayer <= distanceToFollow) {
                targetToWalk = player.transform.position;

                if (currentDistanceToPlayer <= attackRange) {
                    Attack (player);
                }
            }
        }
    }
}

http://docs.unity3d.com/Manual/animeditor-AnimationEvents.html

Ok i create the animation event, the problem is the script its attached to the gameobject player, and the animator is in the real 3d model that is a child of player, so i cant select the attack function in the animation event. Wt can i do to fix it? Its possible to access a function inside a parent sctipt in child object so i can use it in animation event? i try move the script and the nav mesh to the model but then everything gets bugged… -.-

Bump!!! Anyone plz

looks like the functions available to an animationEvent are only the ones attached to the same gameobject the animator is attached to.

You can always include helper functions which use “transform.parent.GetComponent().function”, “GetComponentInParent().function” or “GetComponentInChildren().function” etc.

Ok im behind dumb right now but i just need to create a script called “helper” for example and write in start function:

GetComponentInParent().ApplyDamage;

Cuz i get and error doing this… Ty

as in the general sense. A function that doesn’t really do anything itself but calls other functions in order to make things clearer/simpler.

assuming that’s a direct copy you still need to have proper syntax for the function call (admittedly my listings were sloppy and didn’t :frowning: )

GetComponentInParent<NPCBehavior>().ApplyDamage(5f); // or whatever the parameters are

Although, having said that, this might all be fixing through code issues which really should be fixed through reorganising the structure of the gameobject hierarchy…