Unity의 NetworkTransport를 구현하는 방법에 대한 광범위한 자습서를 읽었습니다. 내가 따라 다니는 동안 모두 의미가 있었지만 완료하고 변경하기 시작했습니다. 나를. 서버와 클라이언트 스크립트간에 모든 것이 어떻게 관련되는지, 서버/클라이언트에 보낼 추가 변수를 추가하는 방법을 이해하려면 약간의 도움이 필요합니다.NetworkTransport : 서버 및 클라이언트에 여러 데이터 보내기
현재 스크립트가있는 곳에서 클라이언트 측에 두 개의 추가 변수 (Texture2D 및 문자열)를 추가하여 플레이어 클래스에 추가하고 서버 및 다른 클라이언트에 전달합니다.
이 두 가지 추가 변수를 Player 클래스에 추가하고 서버 스크립트의 내 ServerClient 클래스에도 동일한 변수를 추가하여 클라이언트 스크립트에서 시작했습니다. 그런 다음 SpawnPlayer 함수의 클라이언트 스크립트에서이 두 가지 추가 변수를 전달하지만 처음 두 변수를 저장하는 올바른 문자열을 어떻게 생성하는지 혼란스러워합니다. 누구든지 올바른 방향으로 나를 가리킬 수 있다면 엄청난 도움이 될 것입니다. 고맙습니다!
'NetworkServerController.cs'
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Text;
public class ServerClient
{
public int connectionID;
public string playerName;
public Texture2D animalTex;
public string animalType;
public Vector3 position;
}
public class NetworkServerController : MonoBehaviour {
private const int MAX_CONNECTION = 10;
private int port = 5701;
private int hostID;
private int webHostID;
private string networkConnections;
private int reliableChannel;
private int unreliableChannel;
private int reliableFragChannel;
private int unreliableFragChannel;
private bool isStarted = false;
private byte error;
private List<ServerClient> clients = new List<ServerClient>();
private float lastMovementUpdate;
private float movementUpdateRate = 0.2f;
// Onscreen Variables
private string connectText;
private string dataText;
private string clientID;
private void Awake()
{
NetworkServer.Reset();
}
private void Start()
{
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.Reliable);
unreliableChannel = cc.AddChannel(QosType.Unreliable);
reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented);
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
hostID = NetworkTransport.AddHost(topo, port);
Debug.Log("Socket Open. HostID is : " + hostID);
webHostID = NetworkTransport.AddWebsocketHost(topo, port);
Debug.Log("Socket Open. webHostID is : " + webHostID);
isStarted = true;
}
int connectionId;
private void Update()
{
if (!isStarted)
{
return;
}
else if (isStarted)
{
// Debug.Log("Server Started.");
int recHostId;
int channelId;
byte[] recBuffer = new byte[1024];
int bufferSize = 1024;
int dataSize;
byte error;
NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
// Network Messenger System
switch (recData)
{
case NetworkEventType.ConnectEvent: //2
Debug.Log("Player " + connectionId + "has connected.");
OnConnection(connectionId);
break;
case NetworkEventType.DataEvent: //3
string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
Debug.Log("Receiving from " + connectionId + " : " + msg);
string[] splitData = msg.Split('|');
switch (splitData[0])
{
case "NAMEIS":
OnNameIs(connectionId, splitData[1]);
break;
case "MYPOSITION":
OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]));
break;
default:
Debug.Log("Invalid message : " + msg);
break;
}
break;
case NetworkEventType.DisconnectEvent: //4
Debug.Log("Player " + connectionId + "has disconnected.");
OnDisconnection(connectionId);
break;
}
// Ask player for their position
if (Time.time - lastMovementUpdate > movementUpdateRate)
{
lastMovementUpdate = Time.time;
string m = "ASKPOSITION|";
foreach (ServerClient sc in clients)
m += sc.connectionID.ToString() + '%' + sc.position.x.ToString() + '%' + sc.position.y.ToString() + '|';
m = m.Trim('|');
Send(m, unreliableChannel, clients);
}
}
}
private void OnConnection(int cnnID)
{
// Add player to list
ServerClient c = new ServerClient();
c.connectionID = cnnID;
c.playerName = "TEMP";
clients.Add(c);
// When player joins server, tell ID
// Request player name and send name of all the other players
string msg = "ASKNAME|" + cnnID + "|";
foreach (ServerClient sc in clients)
msg += sc.playerName + '%' + sc.connectionID + "|";
msg = msg.Trim('|');
// ASKNAME|3|DAVE%1|MIKE%2|TEMP%3
Send(msg, reliableChannel, cnnID);
}
private void OnDisconnection(int cnnId)
{
// Remove this player from our client list
clients.Remove(clients.Find(x => x.connectionID == cnnId));
// Tell everyone that someone has disconnected
Send("DC|" + cnnId, reliableChannel, clients);
}
private void OnNameIs(int cnnID, string playerName)
{
// Link name to connection ID
clients.Find(x => x.connectionID == cnnID).playerName = playerName;
// Tell everone that a new player has connected
Send("CNN|" + playerName + '|' + cnnID, reliableChannel, clients);
}
private void OnMyPosition(int cnnId, float x, float y)
{
clients.Find(c => c.connectionID == cnnId).position = new Vector3(x, y, 0);
}
private void Send(string message, int channelID, int cnnID)
{
List<ServerClient> c = new List<ServerClient>();
c.Add(clients.Find(x => x.connectionID == cnnID));
Send(message, channelID, c);
}
// overload method
private void Send(string message, int channelID, List<ServerClient> c)
{
Debug.Log("Sending : " + message);
byte[] msg = Encoding.Unicode.GetBytes(message);
foreach(ServerClient sc in c)
{
NetworkTransport.Send(hostID, sc.connectionID, channelID, msg, message.Length * sizeof(char), out error);
}
}
}
'NetworkClientController'.cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Text;
public class Player
{
public string playerName;
public GameObject avatar;
public int connectionId;
public Texture2D animalTex;
public string animalType;
}
public class NetworkClientController : MonoBehaviour {
private const int MAX_CONNECTION = 10;
private int port = 5701;
private string IPAddress = "192.168.1.160";
private int hostID;
private int webHostID;
private int reliableChannel;
private int unreliableChannel;
private int reliableFragChannel;
private int unreliableFragChannel;
private int ourClientID;
private int connectionID;
private float connectionTime;
private bool isConnected = false;
private bool isStarted = false;
private byte error;
private string playerName;
public GameObject playerPrefab;
public Dictionary<int, Player> players = new Dictionary<int, Player>();
private void Start()
{
// Connect();
}
public void Connect()
{
// Check player name
string pName = GameObject.Find("NameInput").GetComponent<InputField>().text;
if (pName == "")
{
Debug.Log("You must enter a name");
return;
}
playerName = pName;
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.Reliable);
unreliableChannel = cc.AddChannel(QosType.Unreliable);
reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented);
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
hostID = NetworkTransport.AddHost(topo, port);
connectionID = NetworkTransport.Connect(hostID, IPAddress, port, 0, out error);
connectionTime = Time.time;
isConnected = true;
}
private void Update()
{
if (!isConnected)
return;
int recHostId;
int connectionId;
int channelId;
byte[] recBuffer = new byte[1024];
int bufferSize = 1024;
int dataSize;
byte error;
NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
// Network Messenger System
switch (recData)
{
case NetworkEventType.DataEvent: //3
string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
Debug.Log("Receiving " + msg);
string[] splitData = msg.Split('|');
switch (splitData[0])
{
case "ASKNAME":
OnAskName(splitData);
break;
case "ASKPOSITION":
OnAskPosition(splitData);
break;
case "CNN":
SpawnPlayer(splitData[1], int.Parse(splitData[2]));
break;
case "DC":
PlayerDisconnected(int.Parse(splitData[1]));
break;
default:
Debug.Log("Invalid message : " + msg);
break;
}
break;
}
}
private void OnAskName(string[] data)
{
// Set local client ID
ourClientID = int.Parse(data[1]);
// Send local client name to the server
Send("NAMEIS|" + playerName, reliableChannel);
// Create all remote client players
for(int i = 2; i < data.Length - 1; i++)
{
string[] d = data[i].Split('%');
SpawnPlayer(d[0], int.Parse(d[1]));
}
}
private void OnAskPosition(string[] data)
{
if (!isStarted)
return;
// Update remote client positions
for (int i = 1; i < data.Length - 1; i++)
{
string[] d = data[i].Split('%');
// Prevent the server from updating local client
if (ourClientID != int.Parse(d[0]))
{
Vector3 position = Vector3.zero;
position.x = float.Parse(d[1]);
position.y = float.Parse(d[2]);
players[int.Parse(d[0])].avatar.transform.position = position;
}
}
// Send local client position
Vector3 myPosition = players[ourClientID].avatar.transform.position;
string m = "MYPOSITION" + myPosition.x.ToString() + '|' + myPosition.y.ToString();
Send(m, unreliableChannel);
}
private void SpawnPlayer(string playerName, int cnnId, Texture2D animalTex, string animalType)
{
GameObject go = Instantiate(playerPrefab) as GameObject;
// Is this ours?
if (cnnId == ourClientID)
{
// Add mobility
go.AddComponent<PlayerMovement>();
// Remove Canvas
GameObject.Find("Canvas").SetActive(false);
isStarted = true;
}
Player p = new Player();
p.avatar = go;
p.playerName = playerName;
p.connectionId = cnnId;
p.avatar.GetComponentInChildren<TextMesh>().text = playerName;
p.animalTex = animalTex;
p.animalType = animalType;
players.Add(cnnId, p);
}
private void PlayerDisconnected(int cnnId)
{
Destroy(players[cnnId].avatar);
players.Remove(cnnId);
}
private void Send(string message, int channelID)
{
Debug.Log("Sending : " + message);
byte[] msg = Encoding.Unicode.GetBytes(message);
NetworkTransport.Send(hostID, connectionID, channelID, msg, message.Length * sizeof(char), out error);
}
}
안녕하세요, 당신이 말한 튜토리얼에 대한 링크를 제공 할 수있다? – Fiffe
안녕하세요. @Fiffe 튜토리얼 링크, https://www.youtube.com/watch?v=qGkkaNkq8co – greyBow
감사합니다. @greyBow – Fiffe