Mecanim Stop Animation

Hi guys im using mecanim system for my click to move game, the move and idle part are working properly but now i implement the attack animation, but wt going on is when i press attack the animiation never stop hitting enemy, and if i deactivate loop in animation it just hit one time and stop, but the damage works anyway when i click to attack… can anyone help plz?

I hv a bool for IsAttacking and the following script.

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

public class Player : HumanoidControl
{
    private static Player instance;

    public static Player Instance
    {
        get
        {
            if(instance == null)
            {
                instance = GameObject.FindObjectOfType<Player>();
            }
            return Player.instance;
        }
    }

    public Image healthBar;

    public Text healthtext;

    public static Transform opponent;

    public static Player player;

    bool block;

    private Animator anim;
   
    private bool attacking;


    //character base status
    public int baseIntellect;
    public int baseAgility;
    public int baseStrength;
    public int baseStamina;
   
    //character modified status with equipment
    private int intellect;
    private int agility;
    private int strength;
    private int stamina;

    public Text statsText;

    void Awake()
    {
        player = this;

        anim = GetComponent<Animator>();
    }


    void Start()
    {
        curHealth = maxHealth;

        SetStatus (0, 0, 0, 0);
    }


    void Update()
    {
        healthBar.fillAmount = curHealth / maxHealth;

        healthtext.text = "Health: " + curHealth + "/" + maxHealth;

        Attack();
    }


    public void SetStatus(int intellect, int agility, int strength, int stamina)
    {
        this.intellect = intellect + baseIntellect;
        this.agility = agility + baseAgility;
        this.strength = strength + baseStrength;
        this.stamina = stamina + baseStamina;

        statsText.text = string.Format ("Intellect: {0}\nAgility: {1}\nStrength: {2}\nStamina: {3}", this.intellect, this.agility, this.strength, this.stamina);
    }



    void OnTriggerStay(Collider other)
    {
        /*if (other.name == "Enemy" && curHealth > 0)
        {
            curHealth -= 10;
        }*/
        if (other.name == "HealthRegen")
        {
            curHealth += 10;
        }
        if (curHealth > maxHealth)
        {
            curHealth = maxHealth;
        }
        if (curHealth < 0)
        {
            curHealth = 0;
        }
    }



    protected override void Attack()
    {
        if (Input.GetMouseButtonDown (1))
        {
            if(opponent != null && Vector3.Distance(opponent.position, transform.position) < attackRange)
            {
                opponent.GetComponent<Enemy>().GetHit(damage);

                attacking = true;

                block = true;

                Invoke("UnBlock", attackSpeed);
            }

            if(Vector3.Distance(opponent.position, transform.position) < attackRange && opponent != null)
            {
                attacking = true;
            }
            else
            {
                attacking = false;
            }
            anim.SetBool ("IsAttacking", attacking);
        }
    }



    void UnBlock()
    {
        block = false;
    }
}
if (Input.GetMouseButtonDown (1))
        {
            if(opponent != null && Vector3.Distance(opponent.position, transform.position) < attackRange)
            {
                opponent.GetComponent<Enemy>().GetHit(damage);
                attacking = true;
                block = true;
                Invoke("UnBlock", attackSpeed);
            }
            if(Vector3.Distance(opponent.position, transform.position) < attackRange && opponent != null)
            {
                attacking = true;
            }
            else
            {
                attacking = false;
            }
            anim.SetBool ("IsAttacking", attacking);
        }
else
{
if(opponent != null && Vector3.Distance( opponent.position, transform.position) > attackRange)
            {
                 anim.SetBool ("IsAttacking", false);
            }
         
}

the problem persist, the attack animation just play one time… and not everytime i click right muse button… it gives damage every time i click but animation jkust play in the 1st attack…

I think the animation is looping, did you tried with loop ?

i try with booth… if not looping i need walk between attack to attack animation work again, if i loo, the animation never stop playing hitting only one single time, i need animation to stop after each hit and work again when i attack again…

change IsAttacking to trigger

and i need change enything in code then? and how i connect the attack with other states in animator?

just give it a try you will figure out how to do it

and yes in your code you need to call anim.SeTrigger(“IsAttacking”)

dont work ty anyway if someone else has an idea i will appreciate. ty

could you post your code please ?

the code is up in the thread

anyone plz??? Bump!!

I think you have it half right :slight_smile: You have a GetButtonDown to start the animation, but you need a GetButtonUp to stop the animation :slight_smile: That is what I would suggest :slight_smile:

You could keep it a bool or use multiple triggers. (ie. SetTrigger(“Attack”) and SetTrigger(“StopAttack”) or something like that). Just a thought :smile: but I am sure there are multiple ways of making it work :slight_smile:

So u tell me to use getmousebutton up instead of down? or other way use more bools to start and stop ??? i really dont like mecanims xD or use button down to start and button up to stop?

im more confused then i dont know what… the idle and move part was simple but now implement the atack in the idle/move omg… cuz the logixc and damage is working just fine… but implmente the animations no coments…

and i think the problems is that i hv two scripts 1 to clicktomove and other to player stats and attack… and the things are going like crazy thx to inventory system and character window

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

public class Player : HumanoidControl
{
    private static Player instance;
   
    public static Player Instance
    {
        get
        {
            if(instance == null)
            {
                instance = GameObject.FindObjectOfType<Player>();
            }
            return Player.instance;
        }
    }
   
    public Image healthBar;
   
    public Text healthtext;
   
    public static Transform opponent;
   
    public static Player player;
   
    bool block;
   
    private Animator anim;
   
    private bool attacking;
   
   
    //character base status
    public int baseIntellect;
    public int baseAgility;
    public int baseStrength;
    public int baseStamina;
   
    //character modified status with equipment
    private int intellect;
    private int agility;
    private int strength;
    private int stamina;
   
    public Text statsText;
   
    void Awake()
    {
        player = this;
       
        anim = GetComponent<Animator>();
    }
   
   
    void Start()
    {
        curHealth = maxHealth;
       
        SetStatus (0, 0, 0, 0);
    }
   
   
    void Update()
    {
        healthBar.fillAmount = curHealth / maxHealth;
       
        healthtext.text = "Health: " + curHealth + "/" + maxHealth;
       
        Attack();
    }
   
   
    public void SetStatus(int intellect, int agility, int strength, int stamina)
    {
        this.intellect = intellect + baseIntellect;
        this.agility = agility + baseAgility;
        this.strength = strength + baseStrength;
        this.stamina = stamina + baseStamina;
       
        statsText.text = string.Format ("Intellect: {0}\nAgility: {1}\nStrength: {2}\nStamina: {3}", this.intellect, this.agility, this.strength, this.stamina);
    }
   
   
   
    void OnTriggerStay(Collider other)
    {
        if (other.name == "HealthRegen")
        {
            curHealth += 10;
        }
        if (curHealth > maxHealth)
        {
            curHealth = maxHealth;
        }
        if (curHealth < 0)
        {
            curHealth = 0;
        }
    }
   
   
   
    protected override void Attack()
    {
        if (Input.GetMouseButtonUp (1))
        {
            if(opponent != null && Vector3.Distance(opponent.position, transform.position) < attackRange)
            {
                opponent.GetComponent<Enemy>().GetHit(damage);
               
                attacking = true;

                block = true;
               
                Invoke("UnBlock", attackSpeed);
            }
           
            if(Vector3.Distance(opponent.position, transform.position) < attackRange && opponent != null)
            {
                attacking = true;
            }
            else
            {
                attacking = false;
            }
            anim.SetBool ("IsAttacking", attacking);
        }
    }
   
   
   
    void UnBlock()
    {
        block = false;
    }
}
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;

//[RequireComponent(typeof(NavMeshAgent))]       
public class ClickToMove : MonoBehaviour
{
    private Vector3 targetPosition;               

    const int LEFT_MOUSE_BUTTON = 0;           

    NavMeshAgent navAgent;

    private Animator anim;

    private bool running;


    // Use this for initialization
    void Awake ()
    {
        anim = GetComponent<Animator>();

        navAgent = GetComponent<NavMeshAgent>();
    }



    void Start()
    {
        targetPosition = transform.position;
    }



    // Update is called once per frame
    void Update ()
    {
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            if (Input.GetMouseButton (LEFT_MOUSE_BUTTON))
                SetTargetPosition ();

            MovePlayer ();
        }
    }



    void SetTargetPosition()
    {
        Plane plane = new Plane(Vector3.up, transform.position);
        Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        float point = 0;

        if (plane.Raycast (ray, out point))
            targetPosition = ray.GetPoint (point);
    }



    private void MovePlayer()
    {
        if (GameObject.Find ("MouseOverUI").GetComponent<MouseOverUI>().IsmouseOverGUI)
        {

        }
        else
        {
            running = true;
            navAgent.SetDestination(targetPosition);
            navAgent.Resume();
        }

        if (navAgent.remainingDistance <= navAgent.stoppingDistance)
        {
            running = false;
        }
        else
        {
            running = true;
        }
        anim.SetBool ("IsRunning", running);
    }
}

I am so sorry that was very confusing the way I wrote it.

I think you need a second method of GetButtonUp so you can tell the Animator when to stop the animation :slight_smile: I have a personal example script at home but we just moved so its packed :confused: sorry I couldn’t be of more help!

Appreciate anyway i will try some more things or w8 some kind of help that could appear :wink: Thx m8

and all tutorials for mecanim are for 3rd person view no one for isometric click to move / attack…

1 Like

After some testes i see that when i first hit the attack animation play but after that never stop… the bar above the attack clip in animator is always full so it want treturn to idle… and so never play again… can anyonbe help me plz?

The probleme you have is “you don’t say to mecanim to finish the attack state”, this is why you see the bar full

What you can do :

you can use IsAttacking as bool, in that case you need to call anim.SetBool(“IsAttacking”,false)

from your code this call is inside if(Input.GetMouseButtonDown(1))

so it’ll be execute till the next mouse down, you have to move it from there and check if the normalizetime >= 1, to set it to false

the simple way to do it is with trigger, when you call anim.SetTrigger(“IsAttacking”), you don’t worry about finish or reseting your state, it’ll be automatic if the transition has exit time (this is by default when you create a transition)

 protected override void Attack()
    {
        if (Input.GetMouseButtonDowm (1))
        {
            if(opponent != null && Vector3.Distance(opponent.position, transform.position) < attackRange)
            {
                opponent.GetComponent<Enemy>().GetHit(damage);
             
                attacking = true;
                block = true;
             
                Invoke("UnBlock", attackSpeed);
            }
         
            if(Vector3.Distance(opponent.position, transform.position) < attackRange && opponent != null)
            {
                attacking = true;
          
            anim.SetTrigger ("IsAttacking");
        }
    }

right now in the transition you have IsTrigger == true to play the attack (I am guessing…) if you change it to trigger you will not see any the true/false param, to get back to idle you don’t need any transition condition just the “has exit time” is fine

Hope that help

Finally… Ty m8… Just one other question its possible to player give damage to opponent at certain time of animation?, for example 0.037% of animation time?