Differences

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

Link to this comparison view

pjv:laboratoare:2025:a05 [2025/12/10 12:11]
alexandru.gradinaru
pjv:laboratoare:2025:a05 [2025/12/10 12:46] (current)
alexandru.gradinaru [Cerinte]
Line 32: Line 32:
 ==== Cerinte ===== ==== Cerinte =====
  
-Realizarea unui joc multiplayer de tip social:+Realizarea unui joc multiplayer de tip social, prin folosirea/​implementarea unui server multiplayer dedicat: 
 + 
 + 
 +  * Player avatar sincronizat la nivel de pozitie si animatii: minim 2 playeri/​clienti 
 +  * Comunicare chat cu interfata grafica 
  
-<​hidden>​ 
-  * Player avatar sincronizat la nivel de pozitie si animatii 
-  * Comunicare chat sau voice 
-  * Server multiplayer dedicat, implementare proprie 
-</​hidden>​ 
  
    
Line 132: Line 132:
 Pentru realizarea clientului puteti folosi direct pachetul din Asset Store [[https://​assetstore.unity.com/​packages/​tools/​network/​darkrift-networking-2-95309|DarkRift Networking 2]] Pentru realizarea clientului puteti folosi direct pachetul din Asset Store [[https://​assetstore.unity.com/​packages/​tools/​network/​darkrift-networking-2-95309|DarkRift Networking 2]]
  
-Exemplu de conectare si trimitere de mesaj:+Exemplu de conectare si trimitere de mesaj simplu:
 <​code>​ <​code>​
  
Line 165: Line 165:
  
 Puteti folosi tag-uri pentru a delimita diverse tipuri de mesaje. Puteti folosi tag-uri pentru a delimita diverse tipuri de mesaje.
-De exemplu pentru actualizare de miscare puteti folosi tagul 1 si pentru chat puteti folosi tag-ul ​11+De exemplu pentru actualizare de miscare puteti folosi tagul 1 si pentru chat puteti folosi tag-ul ​10
  
 +Exemplu de trimitere mesaj de chat
 +<​code>​
 +    //This will be called when the user presses enter in the input field
 +    public void MessageEntered()
 +    {
 +        //Check we have a client to send from
 +        if (client == null)
 +        {
 +            Debug.LogError("​No client assigned to Chat component!"​);​
 +            return;
 +        }
  
 +        //First we need to build a DarkRiftWriter to put the data we want to send in, it'll default to Unicode ​
 +        //encoding so we don't need to worry about that
 +        using (DarkRiftWriter writer = DarkRiftWriter.Create())
 +        {
 +            //We can then write the input text into it
 +            writer.Write(input.text);​
  
 +            //Next we construct a message, in this case we can just use a default tag because there is nothing fancy
 +            //that needs to happen before we read the data.
 +            using (Message message = Message.Create(10,​ writer))
 +            {
 +                //Finally we send the message to everyone connected!
 +                client.SendMessage(message,​ SendMode.Reliable);​
 +            }
 +        }
 +    }
 +</​code>​
 +
 +Pentru actualizare miscarii, trebuie sa tinem cont de ficare client in parte: ​
 +  * trimtem actualizari de la input doar pentru clientul curent
 +<​code>​
 +void UpdateNetworkPosition() {
 +        if (
 +            Vector3.Distance(lastPosition,​ transform.position) > moveDistance ||
 +            Vector3.Distance(lastRotation,​ transform.eulerAngles) > moveDistance
 +            ​
 +            )
 +        {
 +            using (DarkRiftWriter writer = DarkRiftWriter.Create())
 +            {
 +                writer.Write(transform.position.x);​
 +                writer.Write(transform.position.y);​
 +                writer.Write(transform.position.z);​
 +                writer.Write(transform.eulerAngles.x);​
 +                writer.Write(transform.eulerAngles.y);​
 +                writer.Write(transform.eulerAngles.z);​
 +
 +                using (Message message = Message.Create(1,​ writer))
 +                    Client.SendMessage(message,​ SendMode.Unreliable);​
 +            }
 +
 +            lastPosition = transform.position;​
 +            lastRotation = transform.eulerAngles;​
 +        }
 +    }
 +</​code>​
 +
 +  * instantiem diferit playerii: unul controlabil din input local, pentru clientul curent, si ceilalti doar sincronizati la actualizarile din server
 +<​code>​
 +void SpawnPlayer(object sender, MessageReceivedEventArgs e)
 +    {
 +
 +        using (Message message = e.GetMessage())
 +        using (DarkRiftReader reader = message.GetReader())
 +        {
 +            if (message.Tag == 0)
 +            {
 +                while (reader.Position < reader.Length)
 +                {
 +                    ​
 +                    ushort id = reader.ReadUInt16();​
 +              ​
 +
 +                    Vector3 position = new Vector3(reader.ReadSingle(),​ reader.ReadSingle(),​ reader.ReadSingle());​
 +                    Vector3 euler = new Vector3(reader.ReadSingle(),​ reader.ReadSingle(),​ reader.ReadSingle());​
 +                    ​
 +                    GameObject obj;
 + 
 +                    if (id == client.ID)
 +                    {
 +                        // instantiate local user
 +                        obj = Instantiate(localPrefab,​ position, Quaternion.identity) as GameObject;
 +                     
 +                    }
 +                    else
 +                    {
 +                        // instantiate network user
 +                        obj = Instantiate(networkPrefab,​ position, Quaternion.identity) as GameObject;
 +                        ​
 +                        //keep a list with all network players
 +                        networkPlayerManager.Add(id,​ playObj);
 +                    }
 +
 +                    ​
 +                }
 +            }
 +        }
 +    }
 +    ​
 +</​code>​
 +  * actualizam sincronizarile din server pentru toti playerii. Pentru asta in general avem nevoie sa tinem minte toata lista de clienti ​
 +<​code>​
 +Dictionary<​ushort,​ NetworkPlayerObj>​ networkPlayers = new Dictionary<​ushort,​ NetworkPlayerObj>​();​
 +
 +void MessageReceived(object sender, MessageReceivedEventArgs e)
 +    {
 +        using (Message message = e.GetMessage() as Message)
 +        {
 +            Debug.Log("​network message ");
 +            if (message.Tag == 1)
 +            {
 +                // Debug.Log("​position message ");
 +                using (DarkRiftReader reader = message.GetReader())
 +                {
 +                    ushort id = reader.ReadUInt16();​
 +                    Vector3 newPosition = new Vector3(reader.ReadSingle(),​ reader.ReadSingle(),​ reader.ReadSingle());​
 +                    Vector3 newEulerAngles = new Vector3(reader.ReadSingle(),​ reader.ReadSingle(),​ reader.ReadSingle());​
 +
 +                    if (networkPlayers.ContainsKey(id))
 +                    {
 +                        // Debug.Log("​new network position: "​+newPosition);​
 +                        networkPlayers[id].movePosition = newPosition;​
 +                        networkPlayers[id].currentEulerAngles = newEulerAngles;​
 +                    }
 +                }
 +            }
 +        }
 +    }
 +</​code>​
 ==== Server Plugin ===== ==== Server Plugin =====
  
Line 335: Line 464:
     }     }
    </​code>​    </​code>​
 +   
 +   
  
 +Pentru sincronizarea de animatii se poate proceda in mai multe feluri, in functie si de modul de gestiune al animatiilor:​
 +     * fie se trimite si un indicator de stare al animatiei si se sincornizeaza over network
 +     * fie se folosesc valori de speed, hieght etc (calculate prin diferenta sau luate/​transmise direct)
 ==== Chat ===== ==== Chat =====
  
pjv/laboratoare/2025/a05.1765361485.txt.gz · Last modified: 2025/12/10 12:11 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