I do Technical Evangelism stuff at Microsoft Greece. Please visit new and updated blog at www.dgkanatsios.com
Please check the new and updated blog at http://www.dgkanatsios.com
Current blog post can be found at http://dgkanatsios.com/2014/07/01/simple-puzzle-game-in-unity-source-code-provided-3/
I had blogged in the past about a simple puzzle game in XNA. Nothing better than to recreate it in Unity with a tutorial, of course! To begin with, here’s a screenshot of the game running on the editor
The purpose of the game is to tap/click on the pieces next to the empty one so that they exchange positions. It goes on and one until you make the pieces appear as in the original photo. Since you are reading this article, I suppose you most probably are a novice Unity user. The following Microsoft Virtual Academy video might be useful for you: http://www.microsoftvirtualacademy.com/training-courses/developing-2d-3d-games-with-unity-for-windows-jump-start
To begin with, we’ll need a photo. The best way to save yourself from copyright issues and not having to read licenses etc is to use a photo that you took! So, we need to slice it. For this purpose, we’ll use Unity’s native 2D tools and its sprite editor.
Once we set the sprite mode to multiple, we can use the sprite editor to ‘slice’ our image. Since the image does not have an alpha channel, we’ll use Grid slicing. Moreover, we’ll name our exported sprites with a name that contains their location information (i.e. piece-0-0 => this implies that the sprite’s “correct” location is on the top left corner of our game). Plus, we’ll set each sprite’s pivot point to be top left, since this will help us in positioning.
In our game, we’ll use a Piece class that contains a) our GameObject (the sprite) and b) relevant information about its current and “correct” positions. Entire code was written in Visual Studio (check out the free Community edition here and the Microsoft Visual Studio Tools for Unity here)
We’ll also have an enumeration for the states of our game plus some constants for our columns and rows count.
Our hierarchy is pretty simple. We have the orthographic camera and our puzzle pieces (which we could also store as prefabs).
The Camera holds the Game script, which is the backbone of our game. We provide the 16 sprites as parameters to the script. Let’s check it out line by line.
At first, we set the state of the game and select a random piece to be blank. We set it as inactive. Then, we take the 16 sprites (imported in a 1D array) and insert them in a 2D array via the Piece class, by assigning all the necessary properties. Plus, we set their positions and add a BoxCollider2D component, if they don’t have one. Last, we set the blank piece to be null.
The GetScreenCoordinatesFromViewport method returns a Vector3 with the world location for each object. The way it works is this; since it’s scanning the viewport, you can imagine the lower left corner to have coordinates (0,0) and the upper right (1,1). So, for instance, a puzzle piece in the second row and in the third column would have coordinates (0.5, 0.75). Below the method we declare some helpful fields and objects for our game.
Our GUI is pretty basic, prompts the user to tap in order to start the game or restart it, if he has won.
Our Update method checks the game state. If we are in the start state and a tap occurs, we shuffle the available pieces and transition to the playing state. If we are in the playing state, we handle the player’s tap events. We also have an animating state, where our piece transitions from the original position to the blank one and finally, an ending state where the user can tap in order to restart the game.
The Shuffle method randomly swaps each puzzle pieces with another one.
The Swap method does the classic work of swapping two objects by using a temp reference. It also sets the correct transforms plus updating the current I and J information.
The CheckPieceInput, running on the playing state of our game, does a raycast upon each player’s tap in order to determine the object that was hit. It loops through all objects in the 2D array to find the correct one. [A prettier way would probably be to attach a MonoBehavior script to each Sprite and find its corresponding Piece reference via its help, but the implemented approach works, nonetheless].
Once we find the Piece that contains the sprite that the user has tapped on, we check its left, its top, its right and its bottom pieces, taking into consideration the game limits (i.e. not to leave the 2D array bounds). If one of them is null, then we have to move the sprite there. Once we find it, we transition to the animating state, where we animate the sprite’s movement to its new position.
The AnimateMovement method (which is running on the animating state) uses the Vector2.MoveTowards method to animate the sprite’s movement to its new location.
On the animating state we also call the CheckIfAnimationEnded method. This method checks if the sprite has completed its animation by comparing the distance of the two transforms. If this is the case, then we call the Swap method to have the moving piece moved properly to the new location plus for it to acquire the relevant current I and J properties. We then switch to the playing state and we also check if the user has won!
The CheckForVictory method checks all Pieces to determine whether all of them are in the correct positions. If one piece is found not to, then the method returns immediately. If all of them are in the correct positions, then the game transitions to the ending state.
As always, if you have any questions or comments feel free to reach to me. You can play the completed game here http://unitysamples.azurewebsites.net/simplepuzzlegame.html Check the project on GitHub https://github.com/dgkanatsios/PuzzleGameUnity Thanks for reading!
PS. Game has been tested on Windows Phone/Store, for instructions on how to deploy your existing game onto Windows Store/Phone, check out the Microsoft Virtual Academy video here: http://www.microsoftvirtualacademy.com/training-courses/porting-unity-games-to-windows-store-and-windows-phone
There is an error.
What should i do?
What kind of error? You should open the project in Unity, select the scene and the game should be playable in the editor.
i just wanna ask you if it is possible to add more pictures for the puzzle and select which one to play with.
Hello, Good day sir!
May I ask for your help?
I'm having trouble in this line
it says that
"IndexOutOfRangeException: Array index is out of range.
PuzzleArrivalCam.Start () (at Assets/scripts/PuzzleArrivalCam.cs:16)"
It is the same code as yours but when I tried it on my own, it is not working.
Its just I used my own picture but I'm having hard times using your code.
Maybe you can help me here?
And thanks for having this great tutorial it helps me a lot! :)
Did you assign the puzzle pieces to the GO script object?
Oh I see sir, I have fixed and used my own picture for the puzzle. Thanks!
But now I intend to have a fixed size for the puzzle because it was depending
on the screen size and I am using this in android devices, so is that possible?
Fixed size will not work well with many devices, so you may bump into other problems :) However, yes, it is possible to alter the coordinates the puzzle pieces are placed.
Oh thanks for answering my questions sir, please bear with me because I wanted to learn.
Could you please give me a clue where should I edit the code for the fixed puzzle size?
And also I am having trouble when I placed the pieces in their right place but it was not recognized as a completed puzzle.
I have followed this code and everything is working well except my puzzle pieces are not forming the image properly. They are aligned but the pieces have quite a bit of space in between all of them. Also when I play your completed game online the pieces are side by side but when I downloaded your unity file and played the scene the same problem occurred; large spaces in between each piece. How can I edit the code to make these come together properly? Or could it be something else that I am doing incorrectly. Please let me know at your earliest.
Check the dimensions on the web player page and modify the Unity Player accordingly
The game doesn't end when is solved, even the web player one.
Should work, will test, have you debugged?
i've tried to change the dimension of the web player but still the game have large spaces between piece. what should i do to change the dimension...??
Powered by Zimbra