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\$

2 Answers 2

0
\$\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\$
1
  • \$\begingroup\$ Testing this right now. :) \$\endgroup\$ Commented Aug 29, 2018 at 21:45
0
\$\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\$
3
  • \$\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\$ Commented Aug 29, 2018 at 11:46
  • \$\begingroup\$ Much cleaner solution indeed! You should definitively post it as an answer! \$\endgroup\$ Commented Aug 29, 2018 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\$ Commented Aug 29, 2018 at 21:45

You must log in to answer this question.