Held Button animation problem

Hi, I have a problem when I held the attack button of my character. I have a shoot animation, but I only want it to be displayed once the shot is fired and not while I’m holding the button down.

This is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour {

    public float maxSpeed = 30;
    public float speed = 5.0f;
    public bool isOnground;

    Transform _transform;
    Rigidbody2D rb;

     Animator anim;


    public float jumpVelocity;

    public float fallm = 3.5f;
    public float lowJumpm = 3f;

    //BALA

    public Transform firePoint;
    public GameObject Bala;
    public GameObject Bala2;
    public float chargetimer = 0;

    public KeyCode chargeshoot;
    public GameObject Charge;

    // Use this for initialization
    void Start () {

        rb = GetComponent <Rigidbody2D> ();
        anim = GetComponent <Animator> ();
    }

    // Update is called once per frame
    void Update () {

        //Move
        anim.SetFloat("velX", Mathf.Abs(rb.velocity.x));
        anim.SetBool ("Grounded", isOnground);
   
        //Salto
        if (Input.GetButtonDown ("Jump") && isOnground) {

            rb.velocity = Vector2.up * jumpVelocity;
            anim.SetBool ("shooting",false);
        }
        if (rb.velocity.y < 0) {


            rb.velocity += Vector2.up * Physics2D.gravity.y * (fallm - 1) * Time.deltaTime;


        } else if (rb.velocity.y > 0 && !Input.GetButton ("Jump")) {

            rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpm - 1) * Time.deltaTime;
        }

    }

    void FixedUpdate (){
   
        //Move
        float h = Input.GetAxis("Horizontal");

        if (h > 0.1f) {
   
            transform.localScale = new Vector3 (1f, 1f, 1f);
        }
        if (h < -0.1f) {

            transform.localScale = new Vector3 (-1f, 1f, 1f);
        }

        rb.AddForce (Vector2.right * speed * h);

        float limitedSpeed = Mathf.Clamp (rb.velocity.x, -maxSpeed, maxSpeed);
        rb.velocity = new Vector2 (limitedSpeed, rb.velocity.y);



        //Shoot
        if (Input.GetKeyDown (KeyCode.A)) {
       
            Instantiate (Bala, firePoint.position, firePoint.rotation);
            if (Input.GetKeyDown (KeyCode.A) && isOnground) {
                anim.SetBool ("shooting", true);
            }

   
        }

   
        if (Input.GetKey (chargeshoot)) {
            chargetimer += Time.deltaTime;
       
            }

        if(Input.GetKeyUp (chargeshoot) && (chargetimer > 1) )  {


            Instantiate (Bala2, firePoint.position, firePoint.rotation);
            chargetimer = 0;
       
            anim.SetBool ("shooting",false);
        }

        if(Input.GetKeyUp (chargeshoot) && (chargetimer < 1)) {

            anim.SetBool ("shooting",false);
            chargetimer = 0;
       
        }


       
        }

(This isn’t the problem you are actually facing, but i want to tell you there is a problem in your script
Checking for Input in fixedUpdate might lead to the input being ignored because inputs get calculated during the Update. Fixed update gets called 50 times a second (usually), Update sometimes gets called faster. If you Input “A”, there is some times an entire frame end before fixedUpdate gets called.)
This is an old code i am using (it isn’t perfect (the naming part and the crossinput part are totally wrong) and it’s only a part of it but it has some ideas about how to make input to work better when using it in fixed update.
Code

public partial class PlatformerCharacterVX

{
    [Header("@~~~~Input Settings (PlatformerCharacterInput.cs)")]

    [SerializeField] private List<string> buttons;



    [Header("_Inspector debugging")]
    public List<Inputbutton> buttonlist;

    partial void StartInput()
    {
        buttonlist = new List<Inputbutton>();
        foreach(string str in buttons)
        {
            buttonlist.Add(new Inputbutton(str));
        }
        var trigone = new Inputbutton("r2");
        trigone.isTrigger = true;
        var trigtwo = new Inputbutton("l2");
        trigtwo.isTrigger = true;
        buttonlist.Add(trigone);
        buttonlist.Add(trigtwo);


    }

    partial void UpdateInput()
    {
        foreach(Inputbutton buto in buttonlist)
        {
            buto.SetActualValue();
        }

    }

    partial void FixedUpdateInput()
    {
      
            foreach (Inputbutton buto in buttonlist)
        {
            if (Getbutton(buto.name, inputtype.down))
            {
                foreach(InterfacePlayerAddon addon in addons)
                {
                    addon.Button(buto.name, inputtype.down);
                }
            }
            buto.getchangedbyfixedupdate();
        }
      

    }

    public bool Getbutton(string name,inputtype type)
    {
        if(type== inputtype.normal)
        {
           // Debug.Log(buttonlist.Find(a => a.name == name).name + "(actual)" + buttonlist.Find(a => a.name == name).actualvalue.ToString());
            return buttonlist.Find(a => a.name == name).actualvalue;

        }
        else if (type == inputtype.down)
        {
            //Debug.Log(buttonlist.Find(a => a.name == name).name + "(down)" + buttonlist.Find(a => a.name == name).buttondown.ToString());
            return buttonlist.Find(a => a.name == name).buttondown;

        }
        else
        {
          //  Debug.Log(buttonlist.Find(a => a.name == name).name + "(up)" + buttonlist.Find(a => a.name == name).buttonup.ToString());

            return buttonlist.Find(a => a.name == name).buttonup;

        }
    }
    public enum inputtype
    {
        normal,
        down,
        up
    }
}



public class Inputbutton
{
    public string name;
    public bool actualvalue;
    public bool previousvalue;
    public bool isTrigger;
    public bool buttondown;
    public bool buttonup;
    public bool gotchangedByFixedInput;

    public Inputbutton(string name)
    {
        this.name = name;
    }

    public void SetActualValue()
    {
        previousvalue = actualvalue;




        if (!isTrigger)
            actualvalue = CrossPlatformInputManager.GetButton(name + "button");
        else
            actualvalue = CrossPlatformInputManager.GetAxis(name + "trigger") > 0.1f;

        if (gotchangedByFixedInput)
        {
            if (!previousvalue & actualvalue)
            {
                buttondown = true;
            }
            else if (previousvalue & !actualvalue)
            {
                buttonup = true;
            }
        }
    }

    public void getchangedbyfixedupdate()
    {
        buttondown = false;
        buttonup = false;
        gotchangedByFixedInput = true;
    }
}

I don’t know what your charging feature keycode is, is it “A” too ?
I’m not sure i understood your problem, is the shoot animation called too early?
Is the shoot animation still called after your character stopeed shooting?

1 Like

Yeah the key code is A too and I’m doing a character that can charge his attack just like megaman, but the problem is that when I hold down the button to charge the attack my character stays in the shoot animation.

In the animator , make the shooting animation to last for something like 0.2 seconds, and to be launched by a trigger.
Instead of anim.SetBool, use anim.SetTrigger. Or maybe you can find a way to make the animator itself set the bool to false after some time.

Another way of doing it would be to add a timer inside your script itself. (the code i will show you is a crappy code, find a better way of doing it , it’s better in the animator)

public float shootimer = 0;

void Update()
{
if(Input.GetKeyDown(chargeshoot)
{
//Instantiate the sutff;
//if is on the ground
shootimer = 0.2;
}

if(shootimer >0)
{
anim.SetBool("shooting",true);
shootimer -= Time.deltaTime;
}
else
{
anim.SetBool("shooting",false);
}
}
1 Like