0
\$\begingroup\$

In my game, the score can go up quite rapidly and by varying amounts, depending on the action taken.

For instance, at the start of the game, one could climb from 1 - 50 one by one, or they could rocket past 50 by getting a score of 10, 25, and 40.

My question is: How do I call a function every time they pass a factor of 50 (50, 100, 150, 200, etc.)?

\$\endgroup\$
1
\$\begingroup\$

Here is code that works by polling the current score. This allows you to separate score-keeping code from the code meant to react to score. You can have multiple score-reactors.

You don't actually need polling. You could make it an event-based system. Add objects with a CheckScore function to a list in your score-keeping class. Then treat that list as a list of callbacks. Or just do it every FixedUpdate.

private long step = 50;
private long nextReward = CurrentScore() + step;

public void CheckScore()
{
    while (CurrentScore() >= nextReward)
    {
        nextReward += step;
        // Give reward here
    }
}

It's also easy replace the while loop with an if then implement a kind of cooldown effect so you don't spawn every reward during the same frame.

private long step = 50;
private long nextReward = CurrentScore() + step;
private int countDown = 0;
private int coolDownFrames = ...;

public void FixedUpdate()
{
    if (CurrentScore() >= nextReward)
    {
        if (countDown == 0)
        {
            countDown = coolDownFrames;
            nextReward += step;
            // Give reward here
        }
        else
        {
            countDown -= 1;
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Testing this right now. :) \$\endgroup\$ – Genevra Aug 29 '18 at 21:45
1
\$\begingroup\$

I would use a property, so that you can modify the score and compute when a step has been passed;

[SerializeField]
private int step = 50;

private int score ;

public int Score
{
    get { return score ; }
    set
    {
        int delta = value - score ;
        if( value > score && value % step < score % step ) // Handle cases such as score = 45 and newScore = 55
        {
            OnStepPassed() ;
        }
        score = value < 0 ? 0 : value ; // Make sure the score is positive
        while( delta >= step )
        {
            delta -= step ;
            OnStepPassed() ;
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ You can make this much simpler as for(int delta = newScore/step - oldScore/step; delta > 0; delta--) OnStepPassed(); The integer division is already present in the modulo, but this way you handle both jumps of one step and jumps of several steps in the same loop. \$\endgroup\$ – DMGregory Aug 29 '18 at 11:46
  • \$\begingroup\$ Much cleaner solution indeed! You should definitively post it as an answer! \$\endgroup\$ – Hellium Aug 29 '18 at 14:13
  • \$\begingroup\$ This is cool, but I'd rather not modify the method of gaining score as I'm already almost done with the game. Thank you though! \$\endgroup\$ – Genevra Aug 29 '18 at 21:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.