How do I "trickle" a function's effect over n seconds?

I’m trying to make a healing skill which yields results gradually over time: as long as you hold the skill button down, there is a random chance that you’ll regain a few hitpoints every half second. However, I’m having a heck of a time with the “holding” part: right now pressing “1” calls my HealOverTime function, which reads as follows:

public void HealOverTime(){
		while (Input.GetKeyDown(KeyCode.Alpha1)){
		       Debug.log("You are trying to heal");
		}

I was hoping this would run continuously, but neither tapping nor holding “1” can get it to produce the debug message and prove it’s firing. Am I missing something obvious, or is this plain the wrongheaded way to go about solving this problem?

Firstly, using while within a function will ‘pause’ and then overload the game, you could use a coroutine and return it at the end of each frame or just use Update and check the key’s pressed.

//called every frame
void Update(){

  //GetKey is checked every frame which is what you'll need
  //GetKeyDown is only return true when the key is initially pressed
  if(Input.GetKey(KeyCode.Alpha1)){
    AttemptHeal();
  }
}

From there just write a simple Heal function based on the Time.time

private float _prevHeal = 0;
    void AttemptHeal(){
      //make sure the time is greater than the previous heal time + 1/2 a second
      if(Time.time > _prevHeal + 0.5f){
        //do heal stuff here
    
        _prevHeal = Time.time;
      }
    }

GetKeyDown will only fire the first time the key is pressed. If you want some kind of auto-fire, you need to use GetKey. Unity - Scripting API: Input.GetKey

Also you DO NOT want to detect the key press in a while loop. Detect it in the Update loop of a MonoBehaviour instead. That while loop will keep other scripts and functions from executing.