how to make combo attack, 1 button do 3 things

need help,
my question is how to make one button do 3 things, cause i want to make combo attack, just like most fighting game.
When i press one time, the button do attack1 animation.
When i press two time, the button do attack1 and attack2 animation. And so on.
this my script :

	private Animator myanim;

	void Start ()
	{
		myanim = GetComponent<Animator>();
		myanim.SetBool ("Attack1", false);
		myanim.SetBool ("Attack2", false);
		myanim.SetBool ("Attack3", false);
	}

	public void Attack1()
	{
		myanim.SetBool ("Attack1", true);
		print("This Attack 1");
	}

	public void Attack2()
	{
		myanim.SetBool ("Attack2", true);
		print("This Attack 2");
	}

	public void Attack3()
	{
		myanim.SetBool ("Attack3", true);
		print("This Attack 3");
	}

// This public void i'm gonna use for ui image button.

2 Answers

2

int noOfClicks = 0;
//Time when last button was clicked
float lastClickedTime = 0;

//Delay between clicks for which clicks will be considered as combo
float maxComboDelay = 1;
void Update()
{
    if(Time.time - lastClickedTime > maxComboDelay)
   {
      noOfClicks = 0;
   }
}

//Call on button click
void OnClick()
{
       //Record time of last button click
       lastClickedTime = Time.time;
       noOfClicks++;
       if( noOfClicks == 1)
      {
                 animator.SetBool("Attack1" , true);
      }

       //limit/clamp no of clicks between 0 and 3 because you have combo for 3 clicks
       noOfClicks =  Mathf.Clamp( noOfClicks , 0 , 3);
}

After this you have to attach StateMachineBehaviour scripts to animation states in animator which will check when state is over.

//Attach this script to Attack1 state in animator
public class PlayerAttack1Behaviour : StateMachineBehaviour {

	 // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
	//override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
	//
	//}

	// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
	//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
	//
	//}

	// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
	override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) 
	{
		animator.SetBool ("Attack1" , false);\

           // Obviously "noOfClicks" is not directly accessible here so you have to make it public and get it reference somehow to use it here 
		if(  noOfClicks >= 2 )
                {
                        animator.SetBool ("Attack2" , true);
                }
	}
	// OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
	//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
	//
	//}

	// OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
	//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
	//
	//}
}

Similarly attach this one to Attack2 state in Animator:

//Attach this script to Attack2 state in animator
 public class PlayerAttack2Behaviour : StateMachineBehaviour {
 
      // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
     //override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
     //
     //}
 
     // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
     //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
     //
     //}
 
     // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
     override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) 
     {
         animator.SetBool ("Attack2" , false);
         if(  noOfClicks >= 3 )
                 {
                         animator.SetBool ("Attack3" , true);
                 }
     }
     // OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
     //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
     //
     //}
 
     // OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
     //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
     //
     //}
 
 
 }

In case you don’t know about StatemachineBehaviours, here is the link to it:

mind of "noOfClicks = Mathf.Clamp( click , 0 , 3);" what click mean ??, i don't create click before,

This is a greate solution, i did that and work awesome https://www.youtube.com/watch?v=xfwty_31Kzc

What are you doing for the state transitions though? I keep getting locked into one attack state because I'm trying to use the attack bools to transition.

it didnt work for me at first but then it worked puting this: if( noOfClicks >= 2 ) { animator.SetBool ("Attack2" , true); } in the update method in player script.

its didnt works for me, onstateexit never getting called, why ??

im experiencing this error…

Assets/Attack1.cs(23,8): error CS0103: The name `noOfClicks’ does not exist in the current context

Did you set 'noOfClicks' as an variable?