1. Trang chủ
  2. » Công Nghệ Thông Tin

Unity multiplayer games

242 725 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 242
Dung lượng 1,76 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Lap trinh game nhieu nguoi choi,ung dung da nen tang,game nhieu nguoi choi,lap trinh game android,lap trinh ung dung android,lap trinh ung dung,viet app android,ky thuat lap trinh,ky thuat ung dung game

Trang 2

Unity Multiplayer Games

Build engaging, fully functional, multiplayer games with Unity engine

Alan R Stagner

BIRMINGHAM - MUMBAI

Trang 3

Unity Multiplayer Games

Copyright © 2013 Packt Publishing

All rights reserved No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews

Every effort has been made in the preparation of this book to ensure the accuracy

of the information presented However, the information contained in this book is sold without warranty, either express or implied Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals However, Packt Publishing cannot guarantee the accuracy of this information.First published: December 2013

Trang 5

About the Author

Alan R Stagner is an independent developer with a passion for Unity3D game

development He was introduced to programming by his father, he sought out different ways to create games in a variety of languages Most recently, he found the Unity game engine and was instantly hooked, and discovered his love of multiplayer game development He has also dabbled in database and server programming from time to time, mostly involving PHP and MySQL with recent forays into ASP.NET

I'd like to thank my family and friends, of course—my father is the

entire reason I'm a programmer and has helped me every step of

the way Everyone I know has been incredibly supportive I'd like

to thank the Unity community—without them I don't think I would

know Unity like I do today I'd also like to thank Unity for providing

such an awesome platform and making it so easy for me to write my

first multiplayer game

Trang 6

About the Reviewers

Clifford Champion has a broad background in software engineering, with years

of experience spanning 3D games and Internet applications, and more recently in machine learning He holds a degree in Mathematics from UCLA In the past, he has worked as an integration and support engineer at Havok, and also as a lead interactive media and Internet apps programmer at PlainJoe Studios

Now, he works for zSpace (zspace.com), a hardware/software company

creating highly immersive, interactive 3D displays for classrooms, industry, and entertainment At zSpace, he is a member of the software platform team, helping to enable the holographic-like experience on a variety of game engines and platforms, including Unity Clifford can be found on Twitter at @duckmaestro and welcomes any discussions

Fabio Ferrara is a game developer He is working for Chubby Pixel, an

independent game studio based in Milan, which he founded in 2012 They work thoroughly to bring to the users the best possible gaming experience He has also

collaborated for the publication of other books such as Unity iOS Essentials,

Packt Publishing.

Sriram A S is a software developer who is currently living in Pune, India He

works primarily in C/C++ and Java He has been working with Unity 3D from its very early versions; and has developed codes related to its integration with

features such as augmented reality, and shared them on his tech blog

(http://mypersonalsoft.blogspot.com)

In his spare time, he works on a few open source software And he also likes to experiment with various other technologies and ideas, along with his team of code passionate friends—the "Hobby Coders" (http://hobbycoders.com)

Trang 7

Support files, eBooks, discount offers, and more

You might want to visit www.packtpub.com for support files and downloads related

to your book

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packtpub.com and as a print book customer, you are entitled to a discount on the eBook copy Get in touch with us at service@packtpub.com for more details

At www.packtpub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers

on Packt books and eBooks

TM

http://PacktLib.PacktPub.com

Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library Here, you can access, read and search across Packt's entire library of books

Why Subscribe?

• Fully searchable across every book published by Packt

• Copy and paste, print and bookmark content

• On demand and accessible via web browser

Free Access for Packt account holders

If you have an account with Packt at www.packtpub.com, you can use this to access PacktLib today and view nine entirely free books Simply use your login credentials

Trang 8

Table of Contents

Preface 1

Setting up a server console without Pro 23

Displaying the score to the player 37

Trang 9

Table of Contents

Chapter 2: Photon Unity Networking – The Chat Client 53

Adding friends lists 76

Trang 11

Table of Contents

Trang 12

This book intends to step you through the concepts and middleware involved

in creating multiplayer games with the Unity game engine I've been a big fan of multiplayer games for a while They have a way of tapping into our basic desires, fulfilling a need to compete, to co-operate, and most of all to socialize with our fellow humans, in a way that no single player game can ever provide

I've experienced a wide range of networking plugins and applications in Unity As

I learn new networking systems, there are always stumbling blocks and difficult issues I wrote this book because I wanted to help others on the same path, and help them surmount the issues I encountered myself

Unity IDE crash course

To better understand this book, we'll need to cover the basic features of the

Unity IDE

If you open Unity for the first time, you'll be presented with a window where you

can either open an existing project or create a new one Select the Create New Project

tab, and choose a location for your project

Once your project is created, you'll see a number of panels There are the Scene and

Game tabs, the Hierarchy, Project, and Console tabs, and the Inspector tab.

The Scene view shows the current scene This will allow you to navigate the scene, select objects, move them around, and more The Game view shows the view of the main camera If you press the Play button, the Game view is automatically shown

and allows you to play test your game from inside the editor

The Hierarchy tab shows the object hierarchy of the current scene This allows you to

select objects, parent or unparent them, delete them, rename them, and much more

Trang 13

The Inspector tab shows the editors for each component attached to the selected

object (rather than being inheritance based like many traditional engines, Unity is component based, where objects are a collection of components and each component has a separate responsibility) It allows you to set values and change properties of components You can also remove components by right clicking on a component and

clicking on Remove Component In Unity 4 and later, you can also click on the Add

Component button and select a component script.

The Project tab shows the assets in your project You can drop game assets here to

import them, and you can create new materials, scripts, and shaders by right-clicking

and selecting the Create option You can also drag objects from the Hierarchy to the Project tab to create a prefab Prefabs are essentially object templates—you can

Instantiate a prefab to create an exact copy of the prefab in the scene (for instance,

you might create an Enemy prefab, and instantiate it to spawn enemies) You can also drag component scripts from the Project to the Inspector of a selected game object to add the component to the object

To learn more about Unity, you can get started here:

http://unity3d.com/learn

What this book covers

Chapter 1, Unity Networking – The Pong Game, introduces the concept of reliable UDP

communication, and different types of servers employed by games It covers Unity Networking, and creating a networked two-player Pong clone

Chapter 2, Photon Unity Networking – The Chat Client, covers a third-party alternative

to Unity Networking It introduces the concept of the cloud-hosted game servers, simple matchmaking, and friends lists It also covers the creation of a simple

chat client

Chapter 3, Photon Server – Star Collector, introduces dedicated servers for games

It covers creating a Photon Server application, connecting to a server, using the request/response/event system to communicate, and creating a simple Star

Collector game

Chapter 4, Player.IO – Bot Wars, covers an alternative dedicated server system It

introduces the database features of Player.IO, how to create a Player.IO server, connecting from Unity, and creating a simple RTS-style game with persistent

user stats

Trang 14

[ 3 ]

Chapter 5, PubNub – The Global Chatbox, introduces communication over an HTTP

messaging service It covers benefits and pitfalls of HTTP for communication, using the WWW class to communicate via PubNub, and creating a chatroom application

Chapter 6, Entity Interpolation and Prediction, introduces the concept of server-side

movement physics and potential issues and solutions It covers client-side movement prediction, and how to smooth the motion of remote entities

Chapter 7, Server-side Hit Detection, introduces the concept of server-side hit detection

for shooter-style games It covers the reasons behind target-leading problems in many online games, and how to resolve the issue by rewinding the game state

What you need for this book

You will need Unity 3 or later for this book Many chapters require specific downloads:

• Chapter 2, Photon Unity Networking – The Chat Client, requires the Photon

Unity Networking plugin

• Chapter 3, Photon Server – Star Collector, requires the Photon Server client and

server SDKs

• Chapter 4, Player.IO – Bot Wars, requires the Player.IO developer package

• Chapter 5, PubNub – The Global Chatbox, requires a third-party JSON parser

Instructions to download the required materials are covered at the beginning of each chapter

Who this book is for

This book is for developers who want to get started writing multiplayer games with the Unity game engine Readers are expected to have a working knowledge of C# Knowledge of the Unity IDE is helpful, but not strictly required

Conventions

In this book, you will find a number of styles of text that distinguish between

different kinds of information Here are some examples of these styles, and an explanation of their meaning

Code words in text are shown as follows: "Navigate to the Release folder and run the EXE."

Trang 15

A block of code is set as follows:

public class ExampleUnityNetworkSerializePosition : MonoBehaviour {

public void OnSerializeNetworkView( BitStream stream,

// send the object's position

Vector3 position = transform.position;

stream.Serialize( ref position );

}

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

// the maximum score a player can reach

public int ScoreLimit = 10;

// the display test for player 1's score

public TextMesh Player1ScoreDisplay;

// the display text for player 2's score

public TextMesh Player2ScoreDisplay;

// Player 1's score

private int p1Score = 0;

New terms and important words are shown in bold Words that you see on the

screen, in menus, or dialog boxes for example, appear in the text like this: "clicking

the Next button moves you to the next screen".

Warnings or important notes appear in a box like this

Tips and tricks appear like this

Trang 16

to develop titles that you really get the most out of.

To send us general feedback, simply send an e-mail to feedback@packtpub.com, and mention the book title via the subject of your message

If there is a topic that you have expertise in and you are interested in either writing

or contributing to a book, see our author guide on www.packtpub.com/authors

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com If you purchased this book

elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes

do happen If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us By doing so, you can save other readers from frustration and help us improve subsequent versions of this book If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the errata submission form link,

and entering the details of your errata Once your errata are verified, your submission will be accepted and the errata will be uploaded on our website, or added to any list of existing errata, under the Errata section of that title Any existing errata can be viewed

by selecting your title from http://www.packtpub.com/support

Trang 17

Piracy

Piracy of copyright material on the Internet is an ongoing problem across all media

At Packt, we take the protection of our copyright and licenses very seriously If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy

Please contact us at copyright@packtpub.com with a link to the suspected

Trang 18

Unity Networking – The Pong Game

Multiplayer is everywhere It's a staple of AAA games and small-budget indie

offerings alike Multiplayer games tap into our most basic human desires Whether

it be teaming up with strangers to survive a zombie apocalypse, or showing off your skills in a round of "Capture the Flag" on your favorite map, no artificial intelligence

in the world comes close to the feeling of playing with a living, breathing, and

thinking human being

Unity3D has a sizable number of third-party networking middleware aimed at

developing multiplayer games, and is arguably one of the easiest platforms to

prototype multiplayer games

The first networking system most people encounter in Unity is the built-in Unity

Networking API This API simplifies a great many tasks in writing networked code

by providing a framework for networked objects rather than just sending messages This works by providing a NetworkView component, which can serialize object state and call functions across the network

Additionally, Unity provides a Master server, which essentially lets players

search among all public servers to find a game to join, and can also help players in connecting to each other from behind private networks

In this chapter, we will cover:

• Introducing multiplayer

• Introducing UDP communication

• Setting up your own Master server for testing

• What a NetworkView is

Trang 19

Unity Networking – The Pong Game

• Serializing object state

• Calling RPCs

• Starting servers and connecting to them

• Using the Master server API to register servers and browse available hosts

• Setting up a dedicated server model

• Loading networked levels

• Creating a Pong clone using Unity networking

Introducing multiplayer games

Before we get started on the details of communication over the Internet, what exactly does multiplayer entail in a game?

As far as most players are concerned, in a multiplayer game they are sharing the same experience with other players It looks and feels like they are playing the same game In reality, they aren't Each player is playing a separate game, each with its own game state Trying to ensure that all players are playing the exact same game

is prohibitively expensive Instead, games attempt to synchronize just enough information to give the illusion of a shared experience

Games are almost ubiquitously built around a client-server architecture, where each client connects to a single server The server is the main hub of the game, ideally the machine for processing the game state, although at the very least it can serve as a simple "middleman" for messages between clients Each client represents an instance

of the game running on a computer In some cases the server might also have a client, for instance some games allow you to host a game without starting up an external server program

While an MMO (Massively Multiplayer Online) might directly connect to one

of these servers, many games do not have prior knowledge of the server IPs For example, FPS games often let players host their own servers In order to show the user a list of servers they can connect to, games usually employ another server, known as the "Master Server" or alternatively the "Lobby server" This server's sole purpose is to keep track of game servers which are currently running, and report

a list of these to clients Game servers connect to the Master server in order to

announce their presence publicly, and game clients query the Master server to get an updated list of game servers currently running

Trang 20

Chapter 1

[ 9 ]

Alternatively, this Master server sometimes does not keep track of servers at all Sometimes games employ "matchmaking", where players connect to the Lobby server and list their criteria for a game The server places this player in a "bucket" based on their criteria, and whenever a bucket is full enough to start a game, a host is chosen from these players and that client starts up a server in the background, which the other players connect to This way, the player does not have to browse servers manually and can instead simply tell the game what they want to play

Introducing UDP communication

The built-in Unity networking is built upon RakNet RakNet uses UDP

communication for efficiency

UDP (User Datagram Protocols) is a simple way to send messages to another

computer These messages are largely unchecked, beyond a simple checksum to ensure that the message has not been corrupted Because of this, messages are not guaranteed to arrive, nor are they guaranteed to only arrive once (occasionally a single message can be delivered twice or more), or even in any particular order TCP,

on the other hand, guarantees each message to be received just once, and in the exact order they were sent, although this can result in increased latency (messages must

be resent several times if they fail to reach the target, and messages must be buffered when received, in order to be processed in the exact order they were sent)

To solve this, a reliability layer must be built on top of UDP This is known as rUDP (reliable UDP) Messages can be sent unreliably (they may not arrive, or may arrive

more than once), or reliably (they are guaranteed to arrive, only once per message, and in the correct order) If a reliable message was not received or was corrupt, the original sender has to resend the message Additionally, messages will be stored rather than immediately processed if they are not in order For example, if you receive messages 1, 2, and 4, your program will not be able to handle those messages until message 3 arrives

Allowing unreliable or reliable switching on a per-message basis affords better overall performance Messages, such as player position, are better suited to

unreliable messages (if one fails to arrive, another one will arrive soon anyway), whereas damage messages must be reliable (you never want to accidentally drop a damage message, and having them arrive in the same order they were sent reduces race conditions)

In Unity, you can serialize the state of an object (for example, you might serialize the position and health of a unit) either reliably or unreliably (unreliable is usually preferred) All other messages are sent reliably

Trang 21

Unity Networking – The Pong Game

Setting up the Master Server

Although Unity provide their own default Master Server and Facilitator (which is connected automatically if you do not specify your own), it is not recommended to use this for production We'll be using our own Master Server, so you know how to connect to one you've hosted yourself

Firstly, go to the following page:

http://unity3d.com/master-server/

We're going to download two of the listed server components: the Master Server and the Facilitator as shown in the following screenshot:

The servers are provided in full source, zipped If you are on Windows using Visual

Studio Express, open up the Visual Studio sln solution and compile in the Release

mode Navigate to the Release folder and run the EXE (MasterServer.exe or Facilitator.exe) If you are on a Mac, you can either use the included XCode project, or simply run the Makefile (the Makefile works under both Linux and

Trang 22

Chapter 1

[ 11 ]

The Master Server, as previously mentioned, enables our game to show a server lobby to players The Facilitator is used to help clients connect to each other by

performing an operation known as NAT punch-through NAT is used when

multiple computers are part of the same network, and all use the same public IP address NAT will essentially translate public and private IPs, but in order for one machine to connect to another, NAT punch-through is necessary You can read more about it here:

http://www.raknet.net/raknet/manual/natpunchthrough.html

The default port for the Master Server is 23466, and for the Facilitator is 50005 You'll need these later in order to configure Unity to connect to the local Master Server and Facilitator instead of the default Unity-hosted servers

Now that we've set up our own servers, let's take a look at the Unity Networking API itself

NetworkViews and state serialization

In Unity, game objects that need to be networked have a NetworkView component

The NetworkView component handles communication over the network, and even helps make networked state serialization easier It can automatically serialize the state of a Transform, Rigidbody, or Animation component, or in one of your own scripts you can write a custom serialization function

When attached to a game object, NetworkView will generate a NetworkViewID

for NetworkView This ID serves to uniquely identify a NetworkView across the network An object can be saved as part of a scene with NetworkView attached (this can be used for game managers, chat boxes, and so on), or it can be saved in the project as a prefab and spawned later via Network.Instantiate (this is used to generate player objects, bullets, and so on) Network.Instantiate is the multiplayer equivalent to GameObject.Instantiate—it sends a message over the network to other clients so that all clients spawn the object It also assigns a network ID to the object, which is used to identify the object across multiple clients (the same object will have the same network ID on every client)

A prefab is a template for a game object (such as the player object)

You can use the Instantiate methods to create a copy of the template in the scene

Trang 23

Unity Networking – The Pong Game

Spawned network game objects can also be destroyed via Network.Destroy It is the multiplayer counterpart of GameObject.Destroy It sends a message to all clients so that they all destroy the object It also deletes any RPC messages associated with that object

NetworkView has a single component that it will serialize This can be a

Transform, a Rigidbody, an Animation, or one of your own components that has

an OnSerializeNetworkView function Serialized values can either be sent with

the ReliableDeltaCompressed option, where values are always sent reliably and

compressed to include only changes since the last update, or they can be sent with

the Unreliable option, where values are not sent reliably and always include the

full values (not the change since the last update, since that would be impossible to predict over UDP) Each method has its own advantages and disadvantages If data

is constantly changing, such as player position in a first person shooter, in general Unreliable is preferred to reduce latency If data does not often change, use the ReliableDeltaCompressed option to reduce bandwidth (as only changes will

be serialized)

NetworkView can also call methods across the network via Remote Procedure Calls (RPC) RPCs are always completely reliable in Unity Networking, although some

networking libraries allow you to send unreliable RPCs, such as uLink or TNet

Writing a custom state serializer

While initially a game might simply serialize Transform or Rigidbody for testing, eventually it is often necessary to write a custom serialization function This is a surprisingly easy task

Downloading the example code

You can download the example code files for all Packt books you have

purchased from your account at http://www.packtpub.com If you

purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you

Here is a script that sends an object's position over the network:

Trang 24

// send the object's position

Vector3 position = transform.position;

stream.Serialize( ref position );

}

// we are currently reading information from the network

else

{

// read the first vector3 and store it in 'position'

Vector3 position = Vector3.zero;

stream.Serialize( ref position );

Using RPCs

RPCs are useful for single, self-contained messages that need to be sent, such as a character firing a gun, or a player saying something in chat

In Unity, RPCs are methods marked with the [RPC] attribute This can be called

by name via networkView.RPC( "methodName", … ) For example, the following script prints to the console on all machines when the space key is pressed

Trang 25

Unity Networking – The Pong Game

ours

if( !networkView.isMine )

return;

// if space key is pressed, call RPC for everybody

if( Input.GetKeyDown( KeyCode.Space ) )

networkView.RPC( "testRPC", RPCMode.All );

}

[RPC]

void testRPC( NetworkMessageInfo info )

{

// log the IP address of the machine that called this RPC

Debug.Log( "Test RPC called from " + info.sender.ipAddress ); }

}

Also note the use of NetworkView.isMine to determine ownership of an object All scripts will run 100 percent of the time regardless of whether your machine owns the object or not, so you have to be careful to avoid letting some logic run on remote machines; for example, player input code should only run on the machine that owns the object

RPCs can either be sent to a number of players at once, or to a specific player

You can either pass an RPCMode to specify which group of players to receive the message, or a specific NetworkPlayer to send the message to You can also specify any number of parameters to be passed to the RPC method

RPCMode includes the following entries:

• All (the RPC is called for everyone)

• AllBuffered (the RPC is called for everyone, and then buffered for when new

players connect, until the object is destroyed)

• Others (the RPC is called for everyone except the sender)

• OthersBuffered (the RPC is called for everyone except the sender, and then

buffered for when new players connect, until the object is destroyed)

• Server (the RPC is sent to the host machine)

Note that, with the exception of RPCMode.All and RPCMode

AllBuffered, a client cannot send an RPC to itself

Trang 27

Unity Networking – The Pong Game

You can also optionally enable an incoming password (useful for private games)

by setting Network.incomingPassword to a password string of the player's choice, and initializing a general-purpose security layer by calling Network.InitializeSecurity() Both of these should be set up before actually initializing the server

Note that incoming connections does not mean maximum player count, since it does not include the host (for example, if you allow

8 players to connect, it's possible for 9 players to play in the same room—8 clients plus the host)

Connecting to a server

To connect to a server you know the IP address of, you can call Network.Connect.The following script allows the player to enter an IP, a port, and an optional password and attempts to connect to the server:

private string port = "";

private string password = "";

void OnGUI()

{

GUILayout.Label( "IP Address" );

ip = GUILayout.TextField( ip, GUILayout.Width( 200f ) );

Trang 29

Unity Networking – The Pong Game

Connecting to the Master Server

While we could just allow the player to enter IP addresses to connect to servers (and many games do, such as Minecraft), it's much more convenient to allow the player to browse a list of public servers This is what the Master Server is for

Now that you can start up a server and connect to it, let's take a look at how to connect to the Master Server you downloaded earlier First, make sure both the Master Server and Facilitator are running I will assume you are running them on your local machine (IP is 127.0.0.1), but of course you can run these on a different computer and use that machine's IP address Keep in mind, if you want the Master Server publicly accessible, it must be installed on a machine with a public IP address (it cannot be in a private network)

Let's configure Unity to use our Master Server rather than the Unity-hosted test server The following script configures the Master Server and Facilitator to connect to

a given IP (by default 127.0.0.1):

Trang 30

Immediately after making a call to Network.InitializeServer, make another call

to MasterServer.RegisterHost This call connects to the Master Server and tells it

to display our server in the public game list

The RegisterHost function takes three parameters, all strings: gameTypeName, gameName, and comment The game type name is used to separate different game listings from each other For example, if two games use the same Master Server, they would both supply different game type names in order to avoid getting listings for the other game The game name is the name of the host server, for example

"John's server" The comment is a general purpose data string, essentially anything can be stored here For example you could store data about the server (such as map rotation, available modes, and so on) and display these to the user while they browse the lobby

Because RegisterHost is a separate call from InitializeServer, you can simply omit the call to RegisterHost to implement private or LAN-style servers

You can call RegisterHost more than once while a server is running

to update the information stored on the Master Server For example,

if the server changes to a new level, you might call RegisterHost again to update the lobby

Browsing available servers

To browse the available servers, call MasterServer.RequestHostList This takes one single parameter: the game type name (this is the same game type name you passed to RegisterHost)

This does not return anything, instead the result will be asynchronously

downloaded, and the last known list of servers can be accessed via MasterServer.PollHostList Additionally, to ensure you aren't using old data, you can call

MasterServer.ClearHostList For example, if the user hits the Refresh button in the lobby you might clear the host list and then request a new list from the

Master Server

Trang 31

Unity Networking – The Pong Game

The following script shows a lobby for users to browse available servers and connect

// are we currently trying to download a host list?

private bool loading = false;

// the current position within the scrollview

private Vector2 scrollPos = Vector2.zero;

HostData[] hosts = MasterServer.PollHostList();

for( int i = 0; i < hosts.Length; i++ )

Trang 32

void OnMasterServerEvent( MasterServerEvent msevent )

The preceding code will list available servers registered to the Master Server

Clicking one of the buttons will call the Network.Connect function and connect

to the corresponding server, and clicking on Refresh will display a Loading

message while results are fetched from the Master Server There are a number of improvements and other tweaks that can be made to this code, left as an exercise for the reader:

• Refresh the host list every few seconds This should be done transparently, without displaying a "Loading" message

• Allow the user to add servers to a "favorites" list (possibly saved as CSV to PlayerPrefs), if your game allows players to run dedicated servers

Trang 33

Unity Networking – The Pong Game

• If the user attempts to connect to a password-protected game (HostData.passwordProtected is true), display a password entry field

• Save game information such as map, mode, and so on in the Comments field

when registering a server, and allow the user to filter server results

Setting up a dedicated server model

Many games allow players to host their own dedicated servers, as separate

applications from the game client Some games even allow players to modify the behavior of the server through scripting languages, allowing player-run servers to employ novel behaviors not originally designed into the game

Let's see how we can set up a similar system in Unity I will not be covering

modding, although readers can look up Lua scripting in Unity—there are a number

of resources on the topic

Servers in Unity

Most games have a specialized "server" build, which contains much the same code as the client, designed to run as a dedicated server This allows the server to process the same logic as the client

Unity, however, does not directly support this concept out of the box Unity Pro does allow builds to be run in "headless mode", which runs the game without initializing any graphics, resources, but the server runs the exact same code as the client The game must be designed to operate in both server and client mode

To do this, we'll take advantage of a compiler feature known as "conditional

compilation" This allows us to wrap code in special tags which allows us to strip out entire sections of code when compiling This way, our server-only code will only be included in server builds, and our client-only code will only be included in client builds

Compiler directives

The first thing we will do, is figure out how the application knows whether it is a client or a server We will use a compiler directive to do this

If you are using Unity 4, you can go to Edit | Project Settings | Player and under

Other Settings is a section that allows you to define these.

Trang 34

Chapter 1

[ 23 ]

However, for any version prior to Unity 4, you'll have to define these yourself To do

this, create a new text file in the Assets folder and name it smcs.rsp Open Notepad and type:

You might consider writing an editor script which replaces the contents of this

file (when compiling for the client, it would replace SERVER with CLIENT, and

vice versa) It is important to note that changes to this file will not automatically recompile, when changing the file you should save one of your scripts Your editor script might do this automatically, for example it could call AssetDatabase

Refresh( ImportAssetOptions.ForceUpdate )

Now that we can detect whether the application was built as a server or a client, we'll need some way for the server to act as autonomously as possible The server should have a configuration file which allows the user to set, for example, network settings before the server runs This book will not cover how to load the configuration file (XML or JSON are recommended), but once these are loaded the server should immediately initialize and register itself with the Master Server using the data in the configuration file (for example, server name, maximum connections, listen port, password, and so on)

Setting up a server console without Pro

Usually, a game server is a console application This is nearly possible in Unity if you have purchased a Pro license, by appending the -batchmode argument to the executable (actually, Unity does not create a console window, instead the game simply runs in the background) If you do have Pro, feel free to skip this section However, if you own a free license, you'll need to get a bit creative

We want the server to use as few resources as possible We can create a script that turns off rendering of the scene when running in server mode This won't completely disable the rendering system (as running in command line would), but it does

significantly reduce the GPU load of the server

using UnityEngine;

using System.Collections;

public class DisableServerCamera : MonoBehavior

Trang 35

Unity Networking – The Pong Game

public string message;

public LogType type;

}

public class CustomLog : MonoBehavior

{

// how many past log messages to store

public int MaxHistory = 50;

// a list of stored log messages

private List<LogMessage> messages = new List<LogMessage>();

// the position within the scroll view

private Vector2 scrollPos = Vector2.zero;

void OnEnable()

{

// register a custom log handler

Application.RegisterLogCallback( HandleLog );

Trang 36

//draw each debug log – switch colors based on log type

for( int i = 0; i < messages.Count; i++ )

{

Color color = Color.white;

if( messages[i].type == LogType.Warning )

// add the message, remove entries if there's too many

LogMessage msg = new LogMessage();

Trang 37

Unity Networking – The Pong Game

// scroll to the newest message by setting to a huge amount

// will automatically be clamped

• As previously mentioned, the server starts up automatically with a

configuration loaded from the user-editable files (unlike the client)

• The server does not spawn any player objects of its own, unlike the client

• The server does not have any UIs or menus to display to the user beyond the log dump Beyond starting up the server and shutting it down, there is zero interaction with the server application

Loading networked levels

There are a few tricks to loading networked levels in the Unity game engine If you just use Application.LoadLevel, you'll encounter a number of issues; specifically you may find that a client connecting to the game won't see any objects that were instantiated via Network.Instantiate The reason for this is because the level loading process doesn't happen instantly—it actually takes two frames to complete This occurs after the list of networked objects was received, so the load process will delete them

Note that Application.LoadLevel is purely client side Unity imposes no

limitations on which level a client or server loads in a networked game In fact, it's entirely possible that you might have different levels within a networked session, and this is what Network.SetLevelPrefix is for Each of these levels is assigned some kind of "ID" that uniquely identifies the level Before loading the level you would use Network.SetLevelPrefix This essentially separates players into

channels, so all players with level prefix 0 are separate from players with level prefix 1, for example

Trang 38

Chapter 1

[ 27 ]

Note that if your game needs all clients to load the same level, you'll have to ensure this yourself If a client has a different level loaded than the host, without setting the level prefix to something different than the host, the client might see some odd situations, such as players floating or sunk into the ground (a player could be standing on a bridge in one level, and a different level at the same position might have a building; so the player would appear to be clipped into the building)

The correct way to load levels in a networked game, is to first disable the network queue, load the level, wait two frames, and then re-enable the network queue This means any incoming messages will not be processed, and will instead be buffered until the new level has completely finished loading

Let's write a simple network level loader that will handle all of these for us

It's designed as a singleton so we don't need one present in the scene (one will automatically be created):

using UnityEngine;

using System.Collections;

public class NetworkLevelLoader : MonoBehavior

{

// implements singleton-style behavior

public static NetworkLevelLoader Instance

{

get

{

// no instance yet? Create a new one

if( instance == null )

private static NetworkLevelLoader instance;

public void LoadLevel( string levelName, int prefix = 0 )

{

StopAllCoroutines();

Trang 39

Unity Networking – The Pong Game

StartCoroutine( doLoadLevel( levelName, prefix ) );

yield return null;

yield return null;

Network.isMessageQueueRunning = true;

Network.SetSendingEnabled( 0, true );

}

}

You can now replace any calls to Application.LoadLevel with

NetworkLevelLoader.Instance.LoadLevel For example, the server might call an RPC which loads the level via the helper class we just wrote, as a buffered RPC so that all clients connecting will automatically load the level

If your server needs to change level during the connection, for example,

in many FPS games players can vote on a new map at the end of a

round, things get a bit more complicated The server should first delete all networked objects belonging to players, remove RPCs from all

players (via Network.RemoveRPCs), and then call the load-level RPC

Creating a multiplayer Pong game

Now that we've covered the basics of using Unity Networking, we're going to apply them to creating a multiplayer Pong clone

The game will play pretty much as standard Pong Players can choose their name, and then view a list of open servers (full rooms will not be shown) Players can also host their own game

Trang 40

Chapter 1

[ 29 ]

Once in a game, players bounce a ball back and forth until it hits the opponent's side Players get one point for this, and the ball will reset and continue bouncing When a player hits 10 points, the winner is called, the scores are reset, and the game continues While in a match with no other players, the server will inform the user

to wait If a player leaves, the match is reset (if the host leaves, the other player is automatically disconnected)

Preparing the Field

First, create a cube (by navigating to GameObject | Create Other | Cube) and scale

it to 1 x 1 x 4 Name it Paddle and set the Tag to Player Check the Is Trigger box on

the collider

Our ball will detect when it hits the trigger zone on the player paddle, and reverse direction We use triggers because we don't necessarily want to simulate the ball realistically with the Unity physics engine (we get far less control over the ball's physics, and it may not behave exactly as we would like)

Ngày đăng: 01/08/2016, 06:47

TỪ KHÓA LIÊN QUAN