• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Step Event... How to Trigger Once? [SOLVED]

C

Chris S.

Guest
Hey guys, is there any way to detect a changed variable in the Step event and then for a loop complete an action only once until the variable changes again?
 

Nux

GameMaker Staff
GameMaker Dev.
To detect a change in variable, you must store the previous value, and compare it with the new value, if they are not equal (a != b) then the variable has changed.

then all you will need to do is put your code into an if conditional with this argument, for example:
Code:
previousVariable = myVariable
myVariable = [get value]
if (previousVariable != myVariable) then
{
    [do code that runs once until the variable changes]
}
 

Tweedle

Member
Hello ! i know it's been checked "solved" but i don't understand the answer :-/

I also need to run code only once when a variable change of state. I could do :
myVariable = 0
if (myVariable = 1) then do that...

Nux suggest storing the previous value and compare it to the new value but I don't see how checking
(previousVariable != myVariable) is different from checking only the actual state of myVariable. It will still be true every step and not only once..

I figure I still haven't understood some basics stuff in GML...
 

NightFrost

Member
Nux's code would run just fine. Let's say myVariable equals five. In the step, you store this value to previousVariable. Then you run whatever code that gives myVariable a new value. Let's say it returns five again. As you next compare the variables, their values are equal, so conditional code block will not run. Next step, you do the same again: previousVariable gains the value five, but as myVariable receives the value of six, the if-check is true (five does not equal six) and the conditional code block runs. The next step over, previousVariable becomes six, and as long as myVariable keeps receiving the value six, the condition will not be true.

Edit: now if the value is being changed externally, that is, object A reaches into object B and changes its values, you'd need to check a little differently.

Code:
CREATE
Value = 0;
OldValue = 0;

STEP
if(Value != OldValue){
    // Stuff
   OldValue = Value;
}
This runs the conditional code only when it detects that Value has changed since last time step event was run.
 
Last edited:

Tweedle

Member
Of course ! I'm so dumb.. OldValue = Value and then in the next step it won't run again. Thanx clever NightFrost :)
 
A

asimnisarahmed

Guest
but what if you don't know the value in variable ?????
 
A

asimnisarahmed

Guest
Then you should find out for yourself what that variable is and what's in it, and stay out of threads that aren't yours.

It's your responsibility to know what's going on in your own projects, not ours. It's also your responsibility to read and obey these posting guidelines.
no Lets Say That if ....

myVariable = random()

then how i would be able to find the value in myVariable??
 

FrostyCat

Redemption Seeker
no Lets Say That if ....

myVariable = random()

then how i would be able to find the value in myVariable??
Then you simply reference myVariable by mentioning it without quotes.

Example:
Code:
myVariable = random(100);
show_message(myVariable);
Another example:
Code:
myVariable = random(100);
if (myVariable <= 50) {
  show_message("50 or less");
} else {
  show_message("More than 50");
}
Note that variable references DO NOT re-run expressions. As a demonstration, if you do this:
Code:
myVariable = random(100);
show_message(myVariable);
show_message(myVariable);
show_message(myVariable);
You will always get the same value from all three popups, random() would run only once for the initial assignment.

Now get out of this thread and make a new one if you still have other things to ask, it's not your place to keep posting here.
 
G

GOD-sSs-END

Guest
Nux's code would run just fine. Let's say myVariable equals five. In the step, you store this value to previousVariable. Then you run whatever code that gives myVariable a new value. Let's say it returns five again. As you next compare the variables, their values are equal, so conditional code block will not run. Next step, you do the same again: previousVariable gains the value five, but as myVariable receives the value of six, the if-check is true (five does not equal six) and the conditional code block runs. The next step over, previousVariable becomes six, and as long as myVariable keeps receiving the value six, the condition will not be true.

Edit: now if the value is being changed externally, that is, object A reaches into object B and changes its values, you'd need to check a little differently.

Code:
CREATE
Value = 0;
OldValue = 0;

STEP
if(Value != OldValue){
    // Stuff
   OldValue = Value;
}
This runs the conditional code only when it detects that Value has changed since last time step event was run.
If I could chime in here, this didn't work for me until I set the value equal to another variable in play. I also couldn't then set the values equal to one another, because the operation I needed to perform was to destroy the instance being manipulated prior to creating a new instance of the same object. So here's another way to do it. Using an existing counter in my game that incremented with each turn, I set the "OldValue" (shown below as "oValue") in the create event. I then set the new "Value" (shown below as "nValue") in the step event. So the code would look like this:

Code:
CREATE:

oValue = global.counter;

STEP:

nValue = global.counter;
if (nValue != oValue) {
   do something;
}
The "oValue" is taken as soon as the object is created. The "nValue" is constantly checked because it's in the step. I know it's unsavory to dig up old posts, but I found this through a search of exactly the problem I was having. Others will too, and now this awesome post is a touch more helpful. My apologies regardless.

Cheers!
 

mortalpoet

Member
Wanted to give my 2-cents. As a beginner, I was running into the same problem, and Googling kept bringing up this same forum post. None of the above solutions worked for what I was trying to do, but I finally figured out a solution that I find easy to read and modify.

It's helped me a lot, and I hope it helps others too that just want to run an event once in a Step Event:

GML:
CREATE:
runActionOnce = false;
runAction = false;


STEP:
if (EXTERNAL_CONDITION == true){
    runActionOnce = true;
}

if (runActionOnce == true && runAction == false){
    runAction = true;
    //DO SOMETHING
}
With a true/false event being triggered on every frame, this will execute the code only once, even though it's in a Step Event, and won't trigger again until you set runActionOnce and runAction both to false again somewhere else. Hope this helps!

Happy coding! :)
 

poliver

Member
Wanted to give my 2-cents. As a beginner, I was running into the same problem, and Googling kept bringing up this same forum post. None of the above solutions worked for what I was trying to do, but I finally figured out a solution that I find easy to read and modify.

It's helped me a lot, and I hope it helps others too that just want to run an event once in a Step Event:

GML:
CREATE:
runActionOnce = false;
runAction = false;


STEP:
if (EXTERNAL_CONDITION == true){
    runActionOnce = true;
}

if (runActionOnce == true && runAction == false){
    runAction = true;
    //DO SOMETHING
}
With a true/false event being triggered on every frame, this will execute the code only once, even though it's in a Step Event, and won't trigger again until you set runActionOnce and runAction both to false again somewhere else. Hope this helps!

Happy coding! :)
Why not just use one flag variable?

GML:
if (EXTERNAL_CONDITION == true) && (runActionOnce = false){
    runActionOnce = true;
    //DO SOMETHING
}
 
Top