Pong with two players!
What is the game?
Pong is the very first game that was ever created. Here two player pads are inside a box facing each other on opposite sides. There's a ball between them and the ball moves in a random direction at the beginning. The player pads must avoid the ball hitting on the walls behind them. If a player pad hits a wall the other player will score a point. If the ball hits anywhere other than the walls behind the player pads then they bounce in the opposite direction. In this version of the game, we are implementing multiplayer. This shall be done using Photon Unity Networking(PUN). With the help of PUN, two separate players can control each player pad and play against each other. They shall join the game via a lobby system where one of them creates a room and the other person joins them.
Why is the game made?
This game is made to demonstrate how multiplayer is done in Unity. We use PUN for this. This helps to establish a server where both players can join and play the game. Since this is my first time doing multiplayer, this seems to be a good place to start. Learning from this would help me develop the game we are trying to make. This game servers as a good starting point and a reference.
How is the game made?
First, we create a 3D project for pong in unity. But set the camera as 2D, this helps us in building the game as it is in 2D.
Now, we shall import the PUN assets into Unity. This is a crucial step. Once we have imported it, we must set up our PUN wizard to connect to the PUN master server.
After this, we create the shapes for the border of the game, we use 4 different cubes, two acts as a goal post and two acts as the top and bottom border to bounce the ball back in. All the walls will have a box collider to interact with the ball.
We also create another cube and name it as a player, this cube will have a rigid body and a box collider. The ball will be a prefab, so we can spawn it again and again after it scores a goal. Similarly, we also create the player pads which will be a prefab and spawn at the start of the game as both players join.
We shall also create a Game Object at a random location, this will be used to hold the PUN script and can hold the ball and pad as values.
We shall also create scripts for the ball, pad and PUN. The ball script will be assigned to the ball prefab. The player pad script will be assigned to the player pad prefab. The PUN script will be assigned to the Game Object we made to hold it.
Now we should code each of the scripts, starting with the PUN script.
void Start() { //This makes sure we can use PhotonNetwork.LoadLevel() on the master client and all clients in the same room sync their level (cont)... PhotonNetwork.AutomaticallySyncScene = true; if (!PhotonNetwork.IsConnected) { //Set the App version before connecting PhotonNetwork.PhotonServerSettings.AppSettings.AppVersion = gameVersion; //Connect to the photon master-server. We use the settings saved in PhotonServerSettings (a .asset file in this project) PhotonNetwork.ConnectUsingSettings(); } }
This will initiate the PUN network, I won't be going through the whole code here, but I have followed the course video shown in the class.
Next is the player pad script:
void Update() { if (photonView.IsMine) { InputMovement(); } } void InputMovement() { if (Input.GetKey(KeyCode.UpArrow)) GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position + Vector3.up * speed * Time.deltaTime); if (Input.GetKey(KeyCode.DownArrow)) GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position - Vector3.up * speed * Time.deltaTime); }
The player pad script is simple. It is used to control the movements of the player pad based on the arrow key pressed.
And last but not least, we have the ball script:
[PunRPC] void ChangeScore(Vector2 score) { Lel(score); if (photonView.IsMine) photonView.RPC("ChangeScore", RpcTarget.OthersBuffered, score); } [PunRPC] void Lel(Vector2 score) { scoreGoalL = score.x; scoreGoalR = score.y; } void OnGUI() { GUI.Label(new Rect(10, 10, 100, 20), "Score " + scoreGoalL + " -- " + scoreGoalR); } [PunRPC] void ChangePositionTo(Vector3 myposition) { GetComponent<Transform>().position = myposition; if (photonView.IsMine) photonView.RPC("ChangePositionTo", RpcTarget.OthersBuffered, myposition); } [PunRPC] void ChangeDirTo(Vector2 mycurrentDir) { currentDir = mycurrentDir; if (photonView.IsMine) photonView.RPC("ChangeDirTo", RpcTarget.OthersBuffered, mycurrentDir); } [PunRPC] void ChangeColorTo(Vector3 color) { GetComponent<Renderer>().material.color = new Color(color.x, color.y, color.z, 1f); if (photonView.IsMine) photonView.RPC("ChangeColorTo", RpcTarget.OthersBuffered, color); }
PunPRC is for Remote Procedure Call which is used to mark methods that needs to be called remotely.
After the all the scripts are done, and everything seems to be in order, we can run our game, we can make a build of our game to open it in another window.
Now, when we click on the window, we can move the pad in that particular window.
Conclusion
With the help of Maria Butt, I was able to create a room and let her join my game, the game is working as intended.
The Pong multiplayer game has set the foundation for my future multiplayer games. Everything I have learned will be translated to my new multiplayer game.
Thank you for your time. Until next time.
Goodbye.
Disclaimer: References to the images can be found by clicking on them.
Subscribe to my newsletter
Read articles from SAEED BASHEER directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by