Slimey Games: RTS-Project part 17

Slimey Games: RTS-Project part 17

Tutorials about Game Development using Unity, MonoDevelop and C#-Scripting

RTS-Project parts 4 to 6 - Buildings and units

RTS-Project parts 7 and 8 - Cursor and movement

RTS-Project parts 9 and 10 - Resources and unit production

RTS-Project part 11 - Set rally point and sell buildings

RTS-Project part 12 - Build a harvester and collect resources

RTS-Project part 13 - Building construction and a new worker unit

RTS-Project part 17- Saving and Loading Players

Unity Sudoku Solver Tutorial - Introduction

Unity Sudoku Solver Tutorial - Part 1 - Drawing the GUI

Unity Sudoku Solver Tutorial - Part 2 - Setting Sudoku numbers

Unity Sudoku Solver Tutorial - Part 3 - Load an example Sudoku

And here goes part 17 Elgar Storms''s RTS-Project. This time I changed a bit more to Elgars version of the project to make it work on the web player as well.RTS Tutorial part 17

The features of this new Version of the RTS-Game are:

- A new main menu to select a player name and a player avatar

In this new version of the RTS project, Elgar implemented a new system to create players and choose a name and avatar. These players can then be saved to a file and loaded the next time the game is run. Unfortunately the way the saving system is implemented does not work in the unity web player. Due to security restrictions, file creation and other parts of unity''s IO system dont work in the unity web player. This is why I had to change the savegame system.

On the other hand, I also implemed a log window for debugging which I found at Zaxis Games'' blog. and combined it with a new game control object.Game Control Object

A game control object usually is a game object, that conatins genral information about a game. It is present in every scene and makes its information available throughout the entire project. To create a game control object, first createa new folder named GameController inside our RTS folder. Then craete a new script named GameControl.cs and add it to the folder.using UnityEngine;

Now create an empty game object called GameControl and add it to either one of the two scenes and drag the script GameControl.cs onto it. now drag the game object GameControl to the GameController folder to make it into a prefab. Add this prefab to all of the scenes.

What this accomplishes is, that we now have a game object that is present in all scenes. If a new scene is loaded, the game controller from the earlier scene is taken into the new scene, exactly as it is.

Let us now add a nice little debugging helper to it. Create a new script inside the GameController folder called MyLog. Add the following code to the script.using UnityEngine;

void HandleLog(string logString, string stackTrace, LogType type)

GUI.TextArea(new Rect(0, 0, Screen.width / 3, Screen.height), myLog);

if (GUI.Button(new Rect(Screen.width - 120, 8, 100, 24), "Hide Log"))

if (GUI.Button(new Rect(Screen.width - 120, 8, 100, 24), "Show Log"))

This debugging logger has been programmed by Zaxis Games. Now add this script to the GameControl prefab. If you start your game now, you should see a button appearing in the upper right, letting you open and close a window. All debug logs and errors are shown inside this window, making debugging easier, especially in the web player. If you dont want the debugging logger activated, just deactivate the Script in the GameController prefab.

Now lets move on to saving the game in the web player. As I wrote earlier, Unity does not allow us to create files from the web player. One (easy way) to store data are the PlayerPrefs. The player preferences are stored in one, standardized location. Data is witten into the PlayerPrefs using key - value combinations. So what we are going to do, is to convert all the data we were going to write into the savegame file into a string. And that string is what we are going to write into the PlayerPrefs.

The first thing we have to change is the Save() method in PlayerManager.cs.public static void Save(){

using(JsonWriter writer=new JsonTextWriter(sw)){

foreach(PlayerDetails player in players) SavePlayer(writer,player);

Debug.Log (string.Format ("Saved serialized data {0}", entiredata));

Note the Debug.Log messages that we are going to be able to trace in the debugging window we added to our game controller.

To be able to access StringBuilder we need to import System.Text.using System.Text;

We encode the whole string as a Base64 string, using the method EncodeTo64. This makes it harder to modify the data we store in the PlayerPrefs. Define the method as follows:static public string EncodeTo64(string toEncode){

byte[] toEncodeAsBytes = ASCIIEncoding.ASCII.GetBytes(toEncode);

string returnValue = Convert.ToBase64String(toEncodeAsBytes);

Right now, saving the game should work. We now want to load the game from the PlayerPrefs. That means we have to change the Load() method.public static void Load(){

string encodedData=PlayerPrefs.GetString("SaveGame",string.Empty);

Debug.Log ("No data for providad key");

Debug.Log ("Encoded savegame data from Playerprefs: "+encodedData);

Debug.Log ("Decoded serialized savegame data from Playerprefs: "+serializedData);

using (JsonTextReader reader=new JsonTextReader(new StringReader(serializedData))){

if((string)reader.Value=="Players")LoadPlayers(reader);

For the decoding of the decoded data in the PlayerPrefs we need to define the method DecodeFrom64:static public string DecodeFrom64(string encodedData) {

byte[] encodedDataAsBytes= Convert.FromBase64String(encodedData);

string returnValue =ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);

You should now be able to save and load the player stats, Debug information should show in the debugging window.

Now, we are going to add some functionality to the player selection screen. Currently we are able to create a new player and to select an existing one. It is not possible to delete existing players, though. I also added a way to add new players without selecting them. So let us first create two methods to simply add (without selection) and delete players in PlayerManager.cs inside the PlayerManager class.public static void AddPlayer(string name, int avatar){

PlayerDetails newPlayer=new PlayerDetails(name, avatar);

public static void DeletePlayer(string name, int avatar){

We are going to call those methods from SelectPlayer.cs, via these two new methods: private void DeletePlayer(){

SelectionList.LoadEntries has to be called to reload the list of players shown inside the player selection list. Now we can add two new buttons to the player selection menu. My menu buttons definition looks like this://menu buttons

float leftPos=ResourceManager.MenuWidth/2-ResourceManager.ButtonWidth/2;

if(GUI.Button (new Rect(leftPos, topPos, ResourceManager.ButtonWidth, ResourceManager.ButtonHeight)

if(GUI.Button (new Rect(leftPos, topPos, ResourceManager.ButtonWidth, ResourceManager.ButtonHeight)

if(GUI.Button (new Rect(leftPos, topPos, ResourceManager.ButtonWidth, ResourceManager.ButtonHeight)

This means, that the location of the area where the players can enter their names has to be changed. //text area for player to type name

float textTop=menuHeight-4*ResourceManager.Padding-3*ResourceManager.ButtonHeight

As well, the method GetMenuItemsHeight has to be accomodated:private float GetMenuItemsHeight(){

if(avatars.Length>0)avatarHeight=avatars[0].height+2*ResourceManager.Padding;

return avatarHeight+3*ResourceManager.ButtonHeight+ResourceManager.TextHeight

If it all worked out, you should now have the below version of the game running (is it a game already?). You should be able to save your player and then, upon restart of the game, unity should load all the players you created.

I hope you liked this post!

The controls are as always:Scroll:

Click to show/hide Unity web player