Posted on

How to make Pong In Unity Lesson 2

Play Classic Pong

In Pong, each player controls his own paddle. The basic Pong game only allows players to move in two directions on the same axis in order to guard their endzone. 

Creative thought: if you wanted to you could allow players to move their paddle in four directions within a boundary zone.

To create the paddle we will start by coding the player controls. First, create a new folder in the project window and call it Scripts. Then create a new C# script and call it PlayerController. Once created double click on it to open it up in your default coding environment.

Once opened, we need to create some new variables.

public string leftKey, rightKey;
public float speed;

Next, we can create a new function for the paddle movement. This will be a void function and you can call it PaddleMovement. There will be no parameters for this function.

Developer’s Insight: Here I want to take some time to talk about what different ways we could go about moving the player’s paddle. First, we will need to check for the player’s input. There are several different input options that we could look for.  If we were building a mobile game we could use touch input or UI buttons. If we were making it for consoles we could read an axis for a thumbstick control but for the sake of this tutorial and to keep things simple we are just going to read in some keyboard keys which is why we have the two string variables.

As for moving the paddles, there are several different methods we could use all of which would be just fine though some may be better than others for this specific game we are creating. we could use the velocity of a Rigidbody. Or we could use a character controller component and the Move function. We could have the paddle lerp to a specific location. This would work well with a finger touch input or mouse click. However, what will work best for our game will be the Translate function.

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
}

Inside your PaddleMovement function, first, check if the player is pressing a keyboard key by using the leftKey variable. Then inside this, if statement, use the transform.Translate function to move the object of this script to the left at the speed of time.deltaTime multiplied by the speed variable. You can then duplicate this if statement once and change it to use the rightKey string and move the paddle to the right. This is the basic controls for the player’s paddle but we now have one problem. The paddle will keep moving even if it reaches the end of the playing field and camera view. To fix this add another “and” condition to your two if statements checking to see if the x position of the paddle is with a set boundary. Lastly, make sure to call your PaddleMovement function in the Update function of this script. 

In the end, this is what our version of the player controller script looks like.

PaddleController.cs

using UnityEngine;

public class PaddleController : MonoBehaviour
{
    public string leftKey, rightKey;
    public float speed;

    // Use this for initialization

    // Update is called once per frame
    void Update()
    {
        PaddleMovement();
    }

    void PaddleMovement()
    {
        if (Input.GetKey(leftKey) && transform.position.x > -4)
        {
            transform.Translate(Vector3.left * Time.deltaTime * speed, Space.World);
        }
        if (Input.GetKey(rightKey) && transform.position.x < 4)
        {
            transform.Translate(Vector3.right * Time.deltaTime * speed, Space.World);
        }
    }
}
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 != "" &amp;&amp; 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 &lt; 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
}

Once you have this script written up we can then save it and go back to Unity.

You will now need to create a prefab for the paddle. The following objects are what constitute our paddle prefab

  • This is an empty object with the PlayerController script attached to it.
    • : This is a 2D sprite object with the paddle image as the sprite. It also has a Box Collider 2D attached to it.

Once you have created this object in your scene turn it into a prefab. First, create a new folder in your project window and call it Prefabs. Then select the topmost object of the paddle prefab and drag it from your hierarchy to the Prefabs folder.

To test your paddle prefab drag on more into your scene by selecting the paddle prefab from your project window and drag it into the hierarchy window. With this object select change the Z rotation of its transform to 180. This will rotate this object around to the other side of the playing field. Now, for the PlayerController script of this second paddle, you will need to change the values of the leftKey and rightKey variables (I suggest J and L).

Now you can click the play button and test your project so far. You should be able to move the bottom paddle back and forth using the A and D keys and the top paddle with J and L. 

Posted on

How to make Pong in Unity Lesson 1

Play Classic Pong

Welcome to the Info Gamer tutorial series and ebook on how to make your very own Pong Clone using Unity. In this ebook, we will take you step by step through all the key mechanics need to build the basic game of Pong. Along the way, we will explain the purpose of each step and what is possible so you can better understand and learn how to make video games.

If you are not familiar with Pong and would to play it first you can play our version here

Preparation

Things you will need

Before we begin there are a few things you will need. 

  • Computer
  • Internet connection
  • Unity Hub
  • Unity editor

If you are viewing this now then we can assume you already have a computer and an internet connection so you are already halfway there. I also assume you already have Unity Hub and a version of the Unity editor installed but if you don’t you can find our tutorial series on how to install Unity here

The version of Unity does not matter.

Once you have everything you need you will then need to create a new Unity project. You will want to use the 2D template. If you need help knowing how to create a new project follow this tutorial here






Once you have these images imported into your project we can then begin designing our scene. We have divided the game scene up into the following objects. (Click the links to see Inspector)

  • : Your empty scene should already have a camera game object called Main Camera. Make sure this object has the following inspector
  • Directional Light: This is another object that should already be in your empty scene. You don’t need to do anything with this object, in fact, you can just delete this object as we will only be using unlit sprites for this game.
  • Environment: This is a new empty object with the following children
    • : This is a sprite object with the black square sprite
    • : This is an empty object with a 2D box collider
    • LeftWall: This is the same as RightWall but with a negative X position.
    • : This is similar to RightWall and LeftWall but the size of the box collider and position are different.
    • EndTwo: This is the same as EndOne but the Y position is negative.
    • : This is a sprite object with the dotted line sprite.
  • : This is a UI canvas object with the following Canvas Scaler setting.
    • : Is a UI text object anchored to the bottom of the canvas with a 0 for the Text field.
    • ScoreTwo: This is the same a ScoreOne but it is anchored to the top of the canvas.
    • : This is another text object anchored to the bottom. This has the following string for the Text field. “< A           D >”
    • Player2Keys: This is the same as Player1Keys but this object is anchored to the top of the canvas and has the following string for its Text field. “< J           L >”
    • : This is a UI Panel object that has its image transparency turned down to zero.
      • : This is a UI Text object used for displaying the winner. The following string is the value of the Text field. “Player _ Wins”
      • : This is a UI Button object.
        • : This is the UI Text object that comes with the default UI Button.
    • EventSystem: This is the Event System object that is created by default when you create a UI Canvas

Note: Do not forget the tags

Here is what your hierarchy should look like.

Here is what your Game View should look like.

Note: Once you have all this created you can then disable the GameOverPanel in your hierarchy.

At this point, you should have the environment for your game scene complete.

Posted on

Play Classic Pong Made with Unity

Play Classic Pong

Play our version of classic Pong that we made with the Unity game engine. Do you want to learn to make classic Pong? Do you want to become a game developer? Do you want to learn how to use the Unity game engine? If so then check out our complete tutorial series on how to recreate classic pong in Unity. In our tutorial series, we will walk you through how to create pong step by step. At the end of the series, you will have your own version of Pong made with Unity.

Learn how to make Pong in Unity here

No post found