Wednesday, September 16, 2015

Points!

Being an arcade monkey ball style game, of course Eruptoid has Points.  It'll have a high score tracker that I'm hoping to be able to upload to a global database that will track scores of players by region and player supplied string (such as name or initials, or maybe facebook name/google+ profile name.  Haven't decided yet).

Anyway, while I was messing around the the UI, converting it from OnGUI to UnityUI, I noticed my points weren't working.  Turns out it was because I forgot to associate the correct score text fields with the right public variables in the game controller script.
Total Score at the Bottom
I had TotalScore in the Level Score TXT field.  Oops

Well, after I fixed it all up, I noticed that my scoring was rather boring.  The ice cubes I currently have set to be worth 100 points.

And then, upon completion of the level, you are awarded points based on the amount of time remaining.  And I had total score calculated only after the level ended, instead of having it increment every time you got new points.

First thing was first, getting total score to keep up with level score.  I had 3 variables, the HiScore variable which was populated from playerprefs, and represented the highest score attained on that level.  Then I had the levelscore variable, which represented the current score on that level.  And then we had TotalScore, which was an accumulation of the scores of the current play session.

Getting the TotalScore to move with the level score wasn't too difficult.  I just had to track the levelscore variable, watch when it changed, and then change the TotalScore variable by the amount of the level score variable.  The code looks something like this:
So, lastScore is an integer that's set to the current levelscore at startup.  Then, every frame, we compare the value of lastScore to levelscore (which changes every time you get a cube), and then if a change is found, we add the amount of change to the TotalScore.  Finally, we set the lastScore and levelscore variables to be equal so that we can continue to monitor changes in levelscore based on its new value.

As I said, once I got to play testing the new arrangement, I noticed that scoring was rather boring and predictable.  Not very arcade-y.  So I thought "why not award points based on how fast the ball is moving".  This was slightly more complicated than the above.  I basically ended up using the velocity of the ball, multiplied by a fudge factor, in order to get a point value, which is added to the score every frame.

Trouble was, my scores are integers (int), and the velocity of the ball is a floating point number.  Since integer math truncates floats to their nearest int, I was getting no points added until I reached a certain speed threshold, and then I was suddenly getting lots of points.  The solution I took was to decrease my fudge factor by a factor of 10 (from 0.1 to 0.01), and then store a floating point variable that, once it reached a value of 1 or higher, would then be added to the level score, and thus the total score through the code above.  I then packaged the whole process into an UpdateScore function, which you can see here:
SpeedScoreRate is my public float fudge factor.  Making it a public variable means I can change its value from the Unity inspector, instead of having to open up the code and edit it directly.

So, now that its all said and done, I call the UpdateScore function once every frame in the Update block, and the player gets awarded extra points for going fast.  Scoring is now a lot less boring.