title: Unity Key Press to Start and Stop
body: <p>I'm not sure what I'm missing in my code here, could someone help? I'm wanting to press Space to start the Blink function repeating (plus some other things, obviously), then press Space again to Stop and continue on to a different State. With the code below, pressing Space will start the Blink function repeating, but pressing Space again does nothing.</p>
  
  <pre><code>    private bool isDown = false;
  
  void Update () {
      if(Input.GetKeyDown (KeyCode.Space)) {
      if (isDown) {
          CancelInvoke("Blink");
          SetState (LightStates.GREEN);
          isDown = false; 
          }
      else {
          SetState (LightStates.OFF);
          GameObject.Find ("GreenLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
          InvokeRepeating ("Blink", 0f, 0.1f);
          isDown = true; 
          }
      }
  }
  </code></pre>
  
  <p>EDIT: Perhaps my use of the word "button" was misinterpreted. I appreciate the coroutine suggestion, but I am looking to find out how to start a function on a key press and stop the action on a key press of the same key. Changing the function to a coroutine didn't get this to work as I still don't know how to implement the key press to start/stop the coroutine.</p>
  
  <p>The end result is the same. Pressing the Space key starts the action and pressing it again does nothing.</p>
  
  <pre><code>bool isBlinking = false;
  IEnumerator blinkCoroutine;
  
  Renderer yellowLight;
  
  void Start()
  {
      blinkCoroutine = blinkCOR();
  
      //CACHE THE Renderer COMPONENT 
      yellowLight = GameObject.Find("YellowLight").GetComponent&lt;Renderer&gt;()
  }
  
  void Update() {
      if (Input.GetKeyDown (KeyCode.Space) &amp;&amp; !isBlinking) { 
          BlinkStart();
      } else if (Input.GetKeyDown (KeyCode.Space) &amp;&amp; isBlinking) {
          BlinkStop();
      }
  }
  
  IEnumerator blinkCOR()
  {
      SetState (LightStates.OFF);
  
      //Everything in the while loop will be called every frame until stopped
      while (true)
      {
          yellowLight.material.color = Color.Lerp(Color.grey, Color.yellow, Mathf.PingPong(Time.time, 1));
          //Wait for the next frame
          yield return null;
      }
  }
  
  void BlinkStart()
  {
      if (!isBlinking)
      {
          isBlinking = true;
          StartCoroutine(blinkCoroutine);
      }
  }
  
  void BlinkStop()
  {
      if (isBlinking)
      {
          StopCoroutine(blinkCoroutine);
          isBlinking = false;
  
          //Restore old state
          SetState (LightStates.GREEN);
      }
  }
  </code></pre>
  
  <p>EDIT: Full code. This is a state machine that switches the traffic light colors on a timer. When in LightStates.RED, user should be able to press space to turn off all "lights" and have the yellow light blink from grey to yellow. When pressing space again, the state machine should restart with the green "light" in StateGreen function.</p>
  
  <pre><code>using UnityEngine;
  using System;
  using System.Collections;
  using System.Collections.Generic;
  
  public class TrafficLightScriptMachine : MonoBehaviour {
  
  private TrafficLight trafficLight;
  private LightStates curState = LightStates.OFF;
  private Dictionary&lt;LightStates, Action&gt; dic = new Dictionary&lt;LightStates, Action&gt;();
  
  private bool isDown = false;
  bool isBlinking = false;
  IEnumerator blinkCoroutine;
  
  // Use this for initialization
  void Start () {
  
      trafficLight = GetComponent&lt;TrafficLight&gt;();
      dic.Add (LightStates.OFF, new Action (StateOff));
      dic.Add (LightStates.RED, new Action (StateRed));
      dic.Add (LightStates.YELLOW, new Action (StateYellow));
      dic.Add (LightStates.GREEN, new Action (StateGreen));
  
      SetState (LightStates.RED);
      blinkCoroutine = blinkCOR();
  
      GameObject.Find ("GreenLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
      GameObject.Find ("RedLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
      GameObject.Find ("YellowLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
  
  
  }
  
  
  
  // Update is called once per frame
  void Update () {
  
      dic[curState].Invoke();
  
  
          if (curState == LightStates.RED &amp;&amp; Input.GetKeyDown (KeyCode.Space) &amp;&amp; !isBlinking) { 
              BlinkStart();
          } else if (Input.GetKeyDown (KeyCode.Space) &amp;&amp; isBlinking) {
              BlinkStop();
          }
  }
  
  IEnumerator blinkCOR()
  {
      SetState (LightStates.OFF);
      while (true)
      {
  
          GameObject.Find ("GreenLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
          GameObject.Find ("YellowLight").GetComponent&lt;Renderer&gt;().material.color = Color.Lerp(Color.grey, Color.yellow, Mathf.PingPong(Time.time, 1));
          //Wait for the next frame
          yield return null;
      }
  }
  
  void BlinkStart()
  {
      if (!isBlinking)
      {
          isBlinking = true;
          StartCoroutine(blinkCoroutine);
      }
  }
  
  void BlinkStop()
  {
      if (isBlinking)
      {
          StopCoroutine(blinkCoroutine);
          isBlinking = false;
          SetState (LightStates.GREEN);
      }
  }
  
  public enum LightStates
  {
      OFF,
      RED,
      YELLOW,
      GREEN,
  
      NUM_STATES
  }
  
  public void StateRed ()
  {
      // if the time passed since reset is greater than the red switch time then switch to yellow state
      if ((trafficLight.GetLightTime()) &gt; (trafficLight.GetRedLight()))
      {
          GameObject.Find ("GreenLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
          GameObject.Find ("RedLight").GetComponent&lt;Renderer&gt;().material.color = Color.red;
          // switch to yellow state
          SetState (LightStates.YELLOW);
          trafficLight.ResetTimeSinceLastTransition();
      }
  }
  
  public void StateYellow ()
  {
      // If the time since the last light transition is greater than the time to stay yellow, transition to green
      if ((trafficLight.GetLightTime()) &gt; (trafficLight.GetYellowLight()))
      {
          GameObject.Find ("RedLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
          GameObject.Find ("YellowLight").GetComponent&lt;Renderer&gt;().material.color = Color.yellow;
          // switch to green state
          SetState (LightStates.GREEN);
          trafficLight.ResetTimeSinceLastTransition();
      }
  }
  
  public void StateGreen ()
  {
      // If the time since the last light transition is greater than the time to stay green, transition to red.
      if ((trafficLight.GetLightTime()) &gt; (trafficLight.GetGreenLight()))
      {
          GameObject.Find ("YellowLight").GetComponent&lt;Renderer&gt;().material.color = Color.grey;
          GameObject.Find ("GreenLight").GetComponent&lt;Renderer&gt;().material.color = Color.green;
          SetState (LightStates.RED);
          trafficLight.ResetTimeSinceLastTransition();
      }
  }
  
  public void StateOff ()
  {
      gameObject.GetComponent&lt;Renderer&gt;().material.color = Color.grey;
  }
  
  public void SetState (LightStates newState)
  {
      curState = newState; 
  }
  
  }
  </code></pre>