Getting parts of functions to execute only the first consecutive frame

Hello,

I’m something of a beginner to programming but not to game development in general. After coding away for some months I feel I’m getting comfortable with it, but there are a few things that I’m still struggling with.

One of these things happen quite often. It is a general problem and has to do with repeated execution of a function over several frames, where I only want a certain aspect of the function to happen on the first execution. An example could be the way the GetButtonDown() function works, where it only returns true the first frame a button is pressed.

If the whole execution of the function happens within a single script, this is generally not a problem. For example, a solution could look like this:

bool firstExecution = true;

void Update() {
   if Input.GetButton("Fire1") {
      MyFunction();
      firstExecution = false;
   }
   else {
      firstExecution = true;
   }
}

void MyFunction(){
   if (firstExecution){
      print("This happens the first frame");
   }
   else {
      print("This happens consecutive frames");
   }
}

However, this way of doing it seems to become increasingly complicated and problematic when calling functions from other scripts, and when wanting to have several instances of the same function running for different objects.

Some general guidelines on how to approach these kinds of issues would be much appreciated. Is there a better way of doing it than the above, or do I need to keep setting up booleans like this for each object that could run a given function?

I hope I am making some sense here. :-p

Thanks,
Jonatan

I usually do the same thing, but keeping the control inside the function: if the boolean flag is set, the function just returns without doing anything. This way you can call the function without checking any control variable - like this:

void Update() {
   if (Input.GetButton("Fire1")){
      MyFunction(); // let the function control itself
   }
}

bool myFunctionDone = false;

void MyFunction(){
   if (myFunctionDone) return; // abort call if already executed
   // MyFunction code goes here
   myFunctionDone = true;
}

Actions which take multiple frames are sort of inherently messy, in my experience. Some developers prefer to avoid them whenever possible, but I don’t think that’s always possible or reasonable. Sometimes you’ve just got to bite the bullet and keep things as organized as you can. The method you’re using is pretty close to some things I’ve done.

You might look into coroutines, which are functions that Unity can execute over multiple frames: Unity - Scripting API: MonoBehaviour.StartCoroutine

Most of the examples have coroutines that wait for X seconds, wait for a WWW download to finish, but you can also just return null to wait until the next frame’s update cycle, like so:

void Start()
{
	StartCoroutine(TwoFrames());
}

IEnumerator TwoFrames()
{
	Debug.Log("called!");
	return null;
	Debug.Log("next frame");
}

You can have multiple calls to the same coroutine running simultaneously, each with its own local variables and so on. This is good if you want them to behave independently, but can also cause its own mess if you’re not careful about it.

Either way, don’t forget that you always have the option of putting together custom data structures and helper functions to assist you in keeping this process orderly. The particular needs will vary depending on what you’re doing.

Trying to answer this question myself… It seems that if you want to do this in one and the same instance of a script, but keep track of the state for several other objects calling one function from outside, you have to include the bool in the function call. For example:

public void MyFunction(bool firstExecution)
{
   if (firstExecution)
   {
      do stuff only first frame;
   }
   else
   {
      do stuff only consecutive frames;
   }
   do stuff that happens both first frame and consecutive frames;
}