Archive for October 2015

So Many Stars

While many game services and platforms have built-in ratings system, there may come a time when you, like me currently, need a way to allow a user to rate your game using a standard 5 star system. I took a bit of time today to put together a scene to handle this.

First I created filled and outline star graphics:

 

Next I created a scene and laid out a couple of buttons and the 5 star outlines:

The stars are Image UI components. The OK button is not interactable until a rating is selected.

Next I added some event triggers to the stars:

The only unusual thing about this is I added a parameter to the standard event handler:

public void StarEnter(GameObject obj)

public void StarExit(GameObject obj)

public void StarClick(GameObject obj)

Since I’m using the same 3 events for all 5 stars I needed a way to tell which star is being handled. I didn’t want to have to go through some convoluted chunk of code to figure out which star the mouse was over. This would have involved doing a raycast from the mouse location and seeing it the ray hit something, then figuring out which star it hit. Once I set up the empty events in my script the Unity UI automatically recognized the need for a GameObject parameter.

Here’s the entire Rating class:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System;
using System.Collections.Generic;

 

public class Rating : MonoBehaviour {

 

    public Image Star1;
    public Image Star2;
    public Image Star3;
    public Image Star4;
    public Image Star5;

 

    public Sprite Star;
    public Sprite StarOutline;

 

    private int _ratingSelected = 0;

 

    public Button OKButton;

 

    void Start()
    {
        //check for existing rating and disable if exists
        if (PlayerPrefs.HasKey("Rating"))
        {
            StarEnter(GameObject.Find(PlayerPrefs.GetInt("Rating").ToString() + "Star"));

 

            _ratingSelected = PlayerPrefs.GetInt("Rating");
        }
    }

 

    public void StarEnter(GameObject obj)
    {
        if (_ratingSelected == 0)
        {
            switch (obj.name)
            {
                case "1Star":
                {
                    Star1.sprite = Star;

 

                    break;
                }
                case "2Star":
                {
                    Star1.sprite = Star;
                    Star2.sprite = Star;

 

                    break;
                }
                case "3Star":
                {
                    Star1.sprite = Star;
                    Star2.sprite = Star;
                    Star3.sprite = Star;

 

                    break;
                }
                case "4Star":
                {
                    Star1.sprite = Star;
                    Star2.sprite = Star;
                    Star3.sprite = Star;
                    Star4.sprite = Star;

 

                    break;
                }
                case "5Star":
                {
                    Star1.sprite = Star;
                    Star2.sprite = Star;
                    Star3.sprite = Star;
                    Star4.sprite = Star;
                    Star5.sprite = Star;

 

                    break;
                }
            }
        }

 

    }

 

    public void StarExit(GameObject obj)
    {
        if (_ratingSelected == 0)
        {
            switch (obj.name)
            {
                case "1Star":
                {
                    Star1.sprite = StarOutline;

 

                    break;
                }
                case "2Star":
                {
                    Star1.sprite = StarOutline;
                    Star2.sprite = StarOutline;

 

                    break;
                }
                case "3Star":
                {
                    Star1.sprite = StarOutline;
                    Star2.sprite = StarOutline;
                    Star3.sprite = StarOutline;

 

                    break;
                }
                case "4Star":
                {
                    Star1.sprite = StarOutline;
                    Star2.sprite = StarOutline;
                    Star3.sprite = StarOutline;
                    Star4.sprite = StarOutline;

 

                    break;
                }
                case "5Star":
                {
                    Star1.sprite = StarOutline;
                    Star2.sprite = StarOutline;
                    Star3.sprite = StarOutline;
                    Star4.sprite = StarOutline;
                    Star5.sprite = StarOutline;

 

                    break;
                }
            }
        }
    }

 


    public void StarClick(GameObject obj)
    {
        _ratingSelected = Convert.ToInt32(obj.name.Substring(0, 1));
        OKButton.interactable = true;
    }

 

    public void OKButton_Click()
    {
        //save rating
        PlayerPrefs.SetInt("Rating", _ratingSelected);
        Application.LoadLevel("Menu");
    }

 

    public void CancelButton_Click()
    {
        Application.LoadLevel("Menu");
    }
}
}

Since we don’t want the player to be able to change a rating once it’s made, the first thing we do is check to see if the player has already rated the game. I’m storing this in the PlayerPrefs for convenience sake. Obviously it should be in a place a little more secure. If the player has already rated the game, we call the StarEnter handler, passing the control for that number of stars, which sets the related number of stars. We then set the _ratingSelected member with the value from the PlayerPrefs key. Since the event handlers don’t do anything if the _ratingSelected member has a value other than 0, this effectively disables them.

The StarExit handler resets the images to the star outline. We could have simply not passed a parameter to it and just reset all of the stars, but I like the consistency of having a parameter for all 3 handlers.

If the player clicks a star, the _ratingSelected member is set and the OK button enabled, allowing the player to save the rating.

Pretty straightforward. If you use this as is, you’ll have to have a scene named “Menu” and Image controls with the names I used or you’ll get an error.

Feel free to comment – is this useful? Would you have done something different? Am I wasting my time here? 🙂