Welcome to our complete series on how to make the simple mobile game ZigZag. Only the first lesson of this series is available to the public. You will need to be a member of our site to get the rest of this series.
For this first lesson, I will show you everything you need to do to set up in your game scene. We will cover the set up of your camera, player’s ball, and platform prefabs. In the next lesson we will dive into some code and we will create a platform generator.
This is the first lesson on how to make ZigZag in Unity. This series is a member-only series so if you would like to gain access to the rest of this series then go sign up as a member today.
In this lesson, we will show you how to set up your Tic Tac Toe project in Unity.
Lesson 2 Scripts
In this lesson, we create some of the basic scripts for our Tic Tac Toe game.
Lesson 3 Onclick Controls
Now we will show you how to create some of the needed on click function for our Tic Tac Toe game.
Lesson 4 More On Click
This lesson continues on with the creation of more on click function for the different buttons we have in the game.
Lesson 5 Winner Check
This lesson will teach you one of the most important mechanics of Tic Tac Toe the checker. This function runs after each turn and is used to see if there is a winner.
Lesson 6 Winner Display
Once we find a winner we then need to display the winner to the screen. Without this function, you are just marking a grid with X’s and O’s.
Lesson 7 Scores
For this lesson, we will show you how to add points to a player’s score when the win a game.
Lesson 8 Rematch
For this lesson, we will work on some of the UI so the players can restart the game when the match is over.
Lesson 9 Player Display
For this lesson, we will show you how to switch the display for who’s turn it is.
Lesson 10 Cat
In this lesson, we will handle the condition if no one wins the game.
Become an Info Gamer Member Today
Sign up as a member and receive more tutorials, code, and assets for FREE!
In this lesson, we will go through all the steps we need to take to set up our Unity project for creating the classic game Snake. We will go over setting up our file system and as well our main game scene.
Lesson 2 Player Movement
In this lesson, we will teach you how to create the snake object and we will show you how to program the basic forward movement of the snake object.
Lesson 3 More Movement
This is the second half to creating the movement of the snake object.
Lesson 4 Changing Direction
Now that we have the basic movement of the snake object we need to program the controls to change the direction of the snake when the player presses a key on the keyboard.
Lesson 5 Growing Size
For this lesson, we will teach you how to program your snake so that it will have a size to its length. This will make it so latter when we program the eating of food the snake can get bigger and bigger.
Lesson 6 Food System
In this lesson, I will show you how to create a food generator. This mechanic makes it so that food will spawn at a random position in your scene, getting us ready for when our snake starts eating the food.
Lesson 7 Scoring
This is where we finally get to program the interaction between the snake and the food objects. This interaction will give a point to the player, make the snake grow by one, respawn the food, and add entertainment to our game.
Lesson 8 Game Over
Although our game now has an entertainment factor it is not any bit challenging which means it is still boring. To fix this we will program the game over for the game which occurs when the player runs into themselves.
Lesson 9 Main Menu
Now that the basics of our game are made we will now show you how to create the main menu for this game and how to program the transition between our menu scene and our game scene.
GameController.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour {
public int clock;
public int maxSize;
public int currentSize;
public int score;
public bool play;
public float speed;
public int NESW;
public int lEdge;
public int rEdge;
public int tEdge;
public int bEdge;
public GameObject snake;
public GameObject food;
public Snake head;
public Snake tail;
public Text scoreText;
// public UnityAds unityAds;
public Vector2 newVect;
public GameObject currentFood;
private Touch initialTouch;
private float distance;
public bool hasTurned;
// Use this for initialization
void OnEnable()
{
Snake.hit += hit;
}
void Start()
{
InvokeRepeating("TimerInvoke", 0, .1f);
FoodFunction();
}
void OnDisable()
{
Snake.hit -= hit;
}
// Update is called once per frame
void Update()
{
ComChangeD();
if(currentFood = null)
{
FoodFunction();
}
}
void TimerInvoke()
{
Movement();
StartCoroutine(checkVisible());
if (currentSize >= maxSize)
{
TailFunction();
}
else
{
currentSize++;
}
hasTurned = false;
}
void Movement()
{
GameObject temp;
newVect = head.transform.position;
switch (NESW)
{
case 0:
newVect = new Vector2(newVect.x, newVect.y + 1);
break;
case 1:
newVect = new Vector2(newVect.x + 1, newVect.y);
break;
case 2:
newVect = new Vector2(newVect.x, newVect.y - 1);
break;
case 3:
newVect = new Vector2(newVect.x - 1, newVect.y);
break;
}
temp = (GameObject)Instantiate(snake, newVect, transform.rotation);
head.SetNext(temp.GetComponent<Snake>());
head = temp.GetComponent<Snake>();
return;
}
void ComChangeD()
{
if (!hasTurned)
{
if (NESW != 2 && (Input.GetKeyDown(KeyCode.UpArrow)|| Input.GetKeyDown(KeyCode.W)))
{
NESW = 0;
hasTurned = true;
}
if (NESW != 3 && (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)))
{
NESW = 1;
hasTurned = true;
}
if (NESW != 0 && (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)))
{
NESW = 2;
hasTurned = true;
}
if (NESW != 1 && (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)))
{
NESW = 3;
hasTurned = true;
}
}
}
void TailFunction()
{
Snake tempSnake = tail;
tail = tail.GetNext();
tempSnake.removeTail();
}
void FoodFunction()
{
int xPos = Random.Range(rEdge, lEdge);
int yPos = Random.Range(bEdge, tEdge);
currentFood = (GameObject)Instantiate(food, new Vector2(xPos, yPos), transform.rotation);
}
IEnumerator CheckRender(GameObject IN)
{
yield return new WaitForEndOfFrame();
if (IN.GetComponent<Renderer>().isVisible == false)
{
if (IN.tag == "Food")
{
Destroy(IN);
FoodFunction();
}
}
}
void hit(string WhatWasSent)
{
if (WhatWasSent == "Food")
{
FoodFunction();
maxSize++;
score++;
scoreText.text = score.ToString();
int temp = PlayerPrefs.GetInt("HighScore");
if (score > temp)
{
PlayerPrefs.SetInt("HighScore", score);
}
}
if (WhatWasSent == "Snake")
{
CancelInvoke("TimerInvoke");
Exit();
}
}
public void Exit()
{
SceneManager.LoadScene(0);
}
void wrap()
{
if (NESW == 0)
{
head.transform.position = new Vector2(head.transform.position.x, -(head.transform.position.y - 1));
}
else if (NESW == 1)
{
head.transform.position = new Vector2(-(head.transform.position.x - 1), head.transform.position.y);
}
else if (NESW == 2)
{
head.transform.position = new Vector2(head.transform.position.x, -(head.transform.position.y + 1));
}
else if (NESW == 3)
{
head.transform.position = new Vector2(-(head.transform.position.x + 1), head.transform.position.y);
}
}
IEnumerator checkVisible()
{
yield return new WaitForEndOfFrame();
if (!head.GetComponent<Renderer>().isVisible)
{
wrap();
}
}
}
Snake.cs
using UnityEngine;
using System.Collections;
using System;
public class Snake : MonoBehaviour {
public Snake next;
static public Action<string> hit;
// static public Action<GameObject> wrap;
public void SetNext(Snake inner)
{
next = inner;
}
public Snake GetNext()
{
return next;
}
public void removeTail()
{
Destroy(this.gameObject);
}
void OnTriggerEnter(Collider other)
{
if(hit != null)
{
hit(other.tag);
}
if (other.tag == "Food")
{
Debug.Log(other.tag);
Destroy(other.gameObject);
}
}
}
MMController.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class MMController : MonoBehaviour {
int HS;
int LS;
public Text HSText;
public Text LSText;
public GameObject mainPanel;
public GameObject settingPanel;
public Color onColor;
public Color offColor;
public Image [] speedBars;
void Start()
{
if(PlayerPrefs.GetInt("Speed") == 0)
{
PlayerPrefs.SetInt("Speed", 10);
}
Speed(PlayerPrefs.GetInt("Speed"));
}
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
void OnEnable()
{
HS = PlayerPrefs.GetInt("HighScore");
LS = PlayerPrefs.GetInt("CurrentScore");
HSText.text = HS.ToString();
LSText.text = LS.ToString();
}
public void PlayFunction()
{
SceneManager.LoadScene(1);
}
public void youTubeLink()
{
Application.OpenURL("https://www.youtube.com/channel/UCyoayn_uVt2I55ZCUuBVRcQ");
}
public void SettingsFunction()
{
mainPanel.SetActive(false);
settingPanel.SetActive(true);
}
public void BackFunction()
{
mainPanel.SetActive(true);
settingPanel.SetActive(false);
}
public void Speed(int value)
{
for (int i = 0; i < value; i++)
{
speedBars[i].color = onColor;
}
for (int i = value; i < 10; i++)
{
speedBars[i].color = offColor;
}
PlayerPrefs.SetInt("Speed", value);
}
}
using Photon.Chat;
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PhotonChatManager : MonoBehaviour, IChatClientListener
{
#region Setup
[SerializeField] GameObject joinChatButton;
ChatClient chatClient;
bool isConnected;
[SerializeField] string username;
public void UsernameOnValueChange(string valueIn)
{
username = valueIn;
}
public void ChatConnectOnClick()
{
isConnected = true;
chatClient = new ChatClient(this);
//chatClient.ChatRegion = "US";
chatClient.Connect(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat, PhotonNetwork.AppVersion, new AuthenticationValues(username));
Debug.Log("Connenting");
}
#endregion Setup
#region General
[SerializeField] GameObject chatPanel;
string privateReceiver = "";
string currentChat;
[SerializeField] InputField chatField;
[SerializeField] Text chatDisplay;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (isConnected)
{
chatClient.Service();
}
if (chatField.text != "" && Input.GetKey(KeyCode.Return))
{
SubmitPublicChatOnClick();
SubmitPrivateChatOnClick();
}
}
#endregion General
#region PublicChat
public void SubmitPublicChatOnClick()
{
if (privateReceiver == "")
{
chatClient.PublishMessage("RegionChannel", currentChat);
chatField.text = "";
currentChat = "";
}
}
public void TypeChatOnValueChange(string valueIn)
{
currentChat = valueIn;
}
#endregion PublicChat
#region PrivateChat
public void ReceiverOnValueChange(string valueIn)
{
privateReceiver = valueIn;
}
public void SubmitPrivateChatOnClick()
{
if (privateReceiver != "")
{
chatClient.SendPrivateMessage(privateReceiver, currentChat);
chatField.text = "";
currentChat = "";
}
}
#endregion PrivateChat
#region Callbacks
public void DebugReturn(DebugLevel level, string message)
{
//throw new System.NotImplementedException();
}
public void OnChatStateChange(ChatState state)
{
if(state == ChatState.Uninitialized)
{
isConnected = false;
joinChatButton.SetActive(true);
chatPanel.SetActive(false);
}
}
public void OnConnected()
{
Debug.Log("Connected");
joinChatButton.SetActive(false);
chatClient.Subscribe(new string[] { "RegionChannel" });
}
public void OnDisconnected()
{
isConnected = false;
joinChatButton.SetActive(true);
chatPanel.SetActive(false);
}
public void OnGetMessages(string channelName, string[] senders, object[] messages)
{
string msgs = "";
for (int i = 0; i < senders.Length; i++)
{
msgs = string.Format("{0}: {1}", senders[i], messages[i]);
chatDisplay.text += "\n" + msgs;
Debug.Log(msgs);
}
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
string msgs = "";
msgs = string.Format("(Private) {0}: {1}", sender, message);
chatDisplay.text += "\n " + msgs;
Debug.Log(msgs);
}
public void OnStatusUpdate(string user, int status, bool gotMessage, object message)
{
throw new System.NotImplementedException();
}
public void OnSubscribed(string[] channels, bool[] results)
{
chatPanel.SetActive(true);
}
public void OnUnsubscribed(string[] channels)
{
throw new System.NotImplementedException();
}
public void OnUserSubscribed(string channel, string user)
{
throw new System.NotImplementedException();
}
public void OnUserUnsubscribed(string channel, string user)
{
throw new System.NotImplementedException();
}
#endregion Callbacks
}