Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pjv:laboratoare:08 [2020/01/08 14:25]
alexandru.gradinaru
pjv:laboratoare:08 [2020/01/15 16:51] (current)
alexandru.gradinaru
Line 1: Line 1:
-====== Multiplayer ======+====== Multiplayer ​(bonus) ​======
  
 Exista mai multe metode de a face un joc controlabil de mai multi jucatori in acelasi timp: Exista mai multe metode de a face un joc controlabil de mai multi jucatori in acelasi timp:
Line 6: Line 6:
  
 ===== Non-network ===== ===== Non-network =====
 +<​hidden>​https://​answers.unity.com/​questions/​1293382/​instance-a-scene-twice-two-worlds-two-cameras-etc.html</​hidden>​
 Pentru jocuri locale de multiplayer se foloseste in general o tehnica de split-screen:​ folosirea mai multor camere care se afiseaza impart viewport-ul intantei locale a jocului [[https://​docs.unity3d.com/​ScriptReference/​Camera-rect.html]]. ​ Pentru jocuri locale de multiplayer se foloseste in general o tehnica de split-screen:​ folosirea mai multor camere care se afiseaza impart viewport-ul intantei locale a jocului [[https://​docs.unity3d.com/​ScriptReference/​Camera-rect.html]]. ​
 +
 +{{ :​pjv:​laboratoare:​inspectorcamera35.png?​200 |}}
  
 Astfel, pentru un split-screen vertical se pot folosi doua camere cu valorile urmatoare pentru ViewPort Rect (x, y, width, height) Astfel, pentru un split-screen vertical se pot folosi doua camere cu valorile urmatoare pentru ViewPort Rect (x, y, width, height)
Line 14: Line 17:
 Camera 2 : (0.5, 0, 0.5, 1) ► right Camera 2 : (0.5, 0, 0.5, 1) ► right
 </​code>​ </​code>​
-{{:​pjv:​laboratoare:​camera_horizontal_splitscreen.png?​600 | }}+{{ :​pjv:​laboratoare:​camera_horizontal_splitscreen.png?​600 |}}
 iar pentru pentru un split-screen orizontal iar pentru pentru un split-screen orizontal
 <​code>​ <​code>​
Line 20: Line 23:
 Camera 2: (0, 0, 1, 0.5) ► bottom Camera 2: (0, 0, 1, 0.5) ► bottom
 </​code>​ </​code>​
-{{:​pjv:​laboratoare:​camera_vertical_splitscreen.png?​600 | }}+{{ :​pjv:​laboratoare:​camera_vertical_splitscreen.png?​600 |}} 
 + 
 +Controlul jucatorilor va trebui sa se codeze separat prin definirea de axe sau taste specifice fiecarui jucator.
  
 +Daca se doreste implementarea unui GUI personalizat/​diferit pentru fiecare jucator, se pot folosi masti de camera ([[https://​docs.unity3d.com/​ScriptReference/​Camera-cullingMask.html|culling masks]]).
 +Se vor plasa toate obiecte Jucatorului 1 intr-un layer separat (de ex Player1Layer),​ si obiectele jucatorului 2 in alt layer (Player2Layer) si se va asigura ca pentru fiecare camera sunt selectate layer-urile corecte (se vor exclude pentru camera 1 layer-ul cu Player2, si pentru camera 2 layer-ul cu Player 1).
  
 +{{ :​pjv:​laboratoare:​layer-cullingmask.png?​200 |}}
  
  
Line 255: Line 263:
 ... ...
  
 +==== DarkRift ====
  
 +[[https://​darkriftnetworking.com/​DarkRift2|DarkRift 2]] este un server dedicat, modular, care implementeaza protocoale de comunicare ca TCP, UDP, dar si cu extensii pentru WebSocket sau RUDP.
 +Pentru integrarea cu Unity, se poate folosi pachetul din Asset Store [[https://​assetstore.unity.com/​packages/​tools/​network/​darkrift-networking-2-95309|DarkRift Networking 2]]
 +
 +Folosind un server dedicat trebuie gestionate mai multe elemente:
 +  * conexiunile si lista curenta de clienti conectati
 +  * datele stocate despre player
 +  * mesajele de update
 +
 +DarkRift foloseste un sistem modular, bazat pe plugin-uri C#, pentru implementarea serverului.
 +Astfel, putem defini un plugin in felul urmator:
 +<​code>​
 +public class NetPlugin : Plugin
 +{
 +
 +    Dictionary<​IClient,​ Player> players = new Dictionary<​IClient,​ Player>​();​
 +
 +    public override bool ThreadSafe => false;
 +
 +    public override Version Version => new Version(1, 2, 5);
 +
 +    public NetPlugin(PluginLoadData pluginLoadData) : base(pluginLoadData)
 +    {
 +        ClientManager.ClientConnected += ClientConnected;​
 +        ClientManager.ClientDisconnected += ClientDisconnected;​
 +    }
 +}
 +</​code>​
 +unde clasa Player reprezinta datele stocate despre player. Spre exemplu se pot stoca date legate de pozitie, rotatie sau id de utilizator.
 +<​code>​
 +public struct Player
 +{
 +    public ushort ID;
 +    public float X, Y, Z;
 +    public float rotX, rotY, rotZ;
 +}
 +</​code>​
 +
 +In momentul in care se conecteaza un client, trebuie realizate urmatoarele lucruri:
 +  * instantierea Player-ului in server
 +  * notificarea tuturor celorlalti clienti conectati de conectarea unui nou player
 +  * trimiterea de informatii despre ceilalti clienti, clientului nou conectat
 +  * ascultarea de mesaje de actualizare
 +
 +<code c#>
 +void ClientConnected(object sender, ClientConnectedEventArgs e)
 +    {
 +        //new player instance
 +        Player newPlayer = new Player();
 +        newPlayer.ID = e.Client.ID;​
 +        newPlayer.X = 0;
 +        newPlayer.Y = 3;
 +        newPlayer.Z = 0;
 +        newPlayer.rotZ = 0;
 +        newPlayer.rotY = 0;
 +        newPlayer.rotZ = 0;
 +
 +        using (DarkRiftWriter newPlayerWriter = DarkRiftWriter.Create())
 +        {
 +            newPlayerWriter.Write(newPlayer.ID);​
 +            newPlayerWriter.Write(newPlayer.X);​
 +            newPlayerWriter.Write(newPlayer.Y);​
 +            newPlayerWriter.Write(newPlayer.Z);​
 +            newPlayerWriter.Write(newPlayer.rotX);​
 +            newPlayerWriter.Write(newPlayer.rotY);​
 +            newPlayerWriter.Write(newPlayer.rotZ);​
 +
 +            //notify other clients
 +            using (Message newPlayerMessage = Message.Create(0,​ newPlayerWriter))
 +            {
 +                foreach (IClient client in ClientManager.GetAllClients().Where(x => x != e.Client))
 +                    client.SendMessage(newPlayerMessage,​ SendMode.Reliable);​
 +            }
 +        }
 +
 +        players.Add(e.Client,​ newPlayer);
 +
 +        using (DarkRiftWriter playerWriter = DarkRiftWriter.Create())
 +        {
 +            foreach (Player player in players.Values)
 +            {
 +                playerWriter.Write(player.ID);​
 +                playerWriter.Write(player.X);​
 +                playerWriter.Write(player.Y);​
 +                playerWriter.Write(player.Z);​
 +                playerWriter.Write(player.rotX);​
 +                playerWriter.Write(player.rotY);​
 +                playerWriter.Write(player.rotZ);​
 +            }
 +            ​
 +            //send all other players data to new client
 +            using (Message playerMessage = Message.Create(0,​ playerWriter))
 +                e.Client.SendMessage(playerMessage,​ SendMode.Reliable);​
 +        }
 +
 +        e.Client.MessageReceived += MovementMessageReceived;​
 +    }
 +</​code>​
  
 ==== Steam ==== ==== Steam ====
Line 273: Line 379:
 ... ...
  
 +===== Cerinte =====
 +
 +Realizarea unui joc multiplayer (network)
 +
 +  * Realizarea unui client si a unui server de networking prin oricare varianta descrisa in laborator (sau altele)
 +  * Clientii (players) trebuie sa vada miscarile si animatiile celorlalti clienti
 +  * Clientii trebuie sa poata interactiona intre ei si cu mediul:
 +    * coliziuni cu mediul (vizibile de catre toti clientii)
 +    * coliziunile dintre playeri afecteaza doar playerii implicati (de ex impuscarea/​lovirea unui alt player ii va lua damage doar acelui player, si se va actualiza interfata grafica doar pentru playerul respectiv)
  
pjv/laboratoare/08.1578486343.txt.gz · Last modified: 2020/01/08 14:25 by alexandru.gradinaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0