Saturday, June 11, 2011

Unity3d + C# + iOS/Android: In-game cheating system

Abstract (if you wanna skip this part, head below for "Description")
Debugging and testing your game in the iOS can be kinda annoyingly hard sometimes when you wanna:
1. change some attributes of your player in the scene, make sure the controls flow well - using cheat codes to change some values or booleans, just like changing it in the inspector when you were working on it in the Unity editor

2. see if you can pass through the levels without crashing - I faced this problem lots of time, mostly because of graphical memory issues on the iPad or lower generations iPhone and iPod Touch

3. change some settings in your scene - spawn lesser enemies (to see if the game won't lags that much with lesser enemies, or how much it can spawn before it gets lag), reducing time.scale (to check collider errors on your player's and enemy's gameObject), etc… a lot of stuff you can do, I'm just stating some of my usage of it.

4. switch to a backup scene - for backing up, in case some unknown bugs screw up your original scene and you wanna to switch it to an extra "hidden" backup scene… Good for when developing a client's game.

5. show off to your friends about your super high (cheated) highscores - originally when I first introduced the system, I try on getting the highest scores (with cheats) and show it off to the rest of the team... it was really fun XD

I know there's something called the UnityRemote 3 where you can play the game remotely using your iOS devices while syncing with your Mac. But for some reason, mine gets pretty laggy, and the graphic will also get (extremely) pixelated-like, very blurry when building 2d games. I'm not sure about the rest of you, but for mine, it happens a lot.

So I got an idea of creating a "cheating system", where I could do some testing stuff while having the game running on my iOS device, with or without syncing it to the Mac.

The so-called "cheating system" is actually a pretty easy thing to build. The idea is to create a bunch of invisible buttons (with number values in them) in the game scene, press those buttons (key in the codes) and it'll activate the cheats and carry out a function that does what you want.

six buttons positioned on the screen in a number pad-like form

I've set up an example scene for testing out the in-game cheating system, or I as I called it the "CheatsManager" in the example file, you can download it here:

1. After you downloaded the package, open up a new unity project or use an existing one. Double click on the downloaded package and you should be able to see a list of stuff that are about to be imported:

cube1 (material), cube2 (material), CheatsManager.cs (script), 
TestScript.cs (script), TestScene (unity scene file)

2. Select import and open up the TestScene. You should be able to spot two cubes lying in the middle of the screen, one red and one blue. 

3. Each of those cubes are attached with a self-illumin material and a TestScript.cs script, while the MainCamera is attached with a CheatsManager script. I'll go into what each of them does a little bit later.

4. Before you click Play, check the Build Setting and make sure that your target platform is for iOS devices, and click "Switch Platform" located beside the "Player Settings" (in case you haven't), to switch the platform to iOS. Same thing, if you're building for Android on a PC. Alternatively, you can simply change the resolution of the PC and Mac build to width: 320, height: 480, but I find switching to smartphone devices way easier as you can switch between portrait and landscape later on.

5. Once all of the above are done, go to the Game view and change the aspect to "iPhone Tall (320 x 480)", and then click Play!

6. Once in the Play mode, six GUI.Buttons will be spawn on the screen.

7. For this test scene, I've already set up some cheat codes, use your mouse and click on the numbers for either of this two cheat codes: "123450" or "012012"... one at a time. 

8. If you succeeded in clicking "123450", the red cube above will enlarge, click the same codes again and it'll shrink back to its original size; while if you clicked on "012012", the blue cube below will Color.Lerp to another color, click the same codes again will change it back to its original color.

9. Now let me explain the "magic" behind this. Click on the Main Camera, and you should be able to find a CheatsManager script attached to it, in the inspector

Here are a number of variables the script contains and what they does:
- Cheat Codes Array (CheatCode class array) 
contains four variables within it:
= Names, the name of the cheat code (optional)
= Codes, the cheat codes
= Target GO, the target's attributes which you wanna change. Not setting anything here will make it call the function from the gameObject it's attached to (Main Camera), assuming the gameObject also has a method of the same name
= Function Name, the name of the function that the targetGO contains in its script.

- Limit Cheat Codes Length (bool)
checking this to true, will limits the length of cheat codes to the amount of cheatCodesLength variable (below).

- Cheat Codes Length (int)
the maximum length of cheat codes (the subsequent cheat codes you had in the Cheat Codes Array's Codes variable must also be at the size of this variable).

- Start Cheat No (int)
the starting cheat button number, default at 0. Decides what number will the cheat buttons start with. If leaves it at default, the button sequence will be "012345" (depends on the number of buttons); setting it to "1" will change the sequence to "123456".

- Cheat Button Column (int)
the number of columns cheat buttons have.

- Cheat Button Row (int)
the number of rows cheat buttons have.

By multiplying the amount of column and row, you'll get the number of buttons which will be spawn in the scene when game starts.

- Show Button (bool)
checking this to true, will shows the GUI.Buttons on the screen in Play mode; while at false, it won't, but still press-able. It's only replaced with a blank GUIStyle that makes the buttons invisible.

- Type Cheats Time (float)
how long you can type the cheat codes before it resets, defaulted at 2, means when you stop typing the codes, it'll take 2 seconds to reset everything so that you can type again.

Sample Exercise
Assuming you wanna to change the size of the blue cube, and blue cube has a script inside it which contains a function called "ChangeSomething" which does all that
i. All you have to do is to click on the blue cube, look for a variable in its TestScript.cs called the "changeType", change the value from "color" to "size"

ii. Then click on the Main Camera again, and change the size of the CheatCodesArray to 3. Name it to "Change Cube2's Size" (optional), then randomly write a cheat codes at the length of 6 (I'm using "123123").

iii. Drag the blue cube gameObject from the Hierarchy to the Target GO variable, then change the function name to the name of the function you want to call, which in this case, is "ChangeSomething"... insert that in. 

iv. When the game is in Play mode, and the desired cheat codes is pressed in, it'll call the function that change the size of the blue cube from within the CheatsManager script, using SendMessage(). And then the blue cube will start changing size.

If it works, then congrats, you've just made a successful cheats! But if it doesn't, please go through the sample exercise again. 

Feel free to test around with the variables value in the inspector if you like, but don't mess around with the CheatsManager scripts unless if you know what you're doing.

Again, if you wanna to create an entirely new gameObject with an entirely new script, you just have to create a new space in the CheatCodesArray, set new cheat codesdrag in the gameObject to Target GO and then set the function name.

Also, it'll work just the same after you built it into an iOS device, but remember to check off the Show Button variable in the Main Camera's CheatsManager script if you don't want those GUI.Buttons to appear and hide your game or darken it a little... And it'll also change button size and positions once you change the device orientation from portrait to landscape. I haven't really check out this part yet (got some problem with my iPod at the moment), but if you have problem with inputing cheat codes in landscape orientation, send me a report/message at :D

No comments: