【问题标题】:Unity 3D: Send data from client to clientUnity 3D:从客户端向客户端发送数据
【发布时间】:2015-01-08 02:02:38
【问题描述】:

我正在尝试从客户端向客户端发送数据,但它似乎不起作用。我正在使用 Unitys MasterServer。当我将数据从服务器发送到客户端和客户端到服务器时,它工作正常。

我正在使用 RPC 发送数据。是否可以从客户端向客户端发送数据,或者我必须重写我的代码,以便我从客户端 1 向服务器发送一个 RPC 调用,然后从服务器向客户端 2 发送一个新的 RPC 调用?

这里我调用了RPC函数:

networkView.RPC("UpdateBombIncoming", playerPurple);

这是我的 RPC:

[RPC]
void UpdateBombIncoming(){
    Debug.Log ("Bomb is incoming");
    bombIncoming = true;
}

这是我的网络代码:

公共类 NetworkManager : MonoBehaviour {

public int maxNumberOfPlayers = 3;
public int port = 25002;
public int playerID;
public NetworkPlayer playerBlue;        // Server
public NetworkPlayer playerPurple;
public NetworkPlayer playerGreen;
public int playerColor;                 // 1: blue, 2: purple, 3: green
public Font myFont;
public int playerCount;

private SceneManager sceneManager;
private bool showPlayersOnGUI;

string registeredGameName = "Bomba_Alpha";
bool isRefreshing = false;
float RefreshRequestLength = 3.0f;
HostData[] hostData;

void Awake(){


}

void Start(){
    sceneManager = GetComponent<SceneManager>();
}


 void Update(){

    Debug.Log("Blue Player connected from " + playerBlue.ipAddress + ":" + playerBlue.port);
    Debug.Log("Purple Player connected from " + playerPurple.ipAddress + ":" + playerPurple.port);
    Debug.Log("Green Player connected from " + playerGreen.ipAddress + ":" + playerGreen.port);
    Debug.Log("Players connected to server " + playerCount);

    // When player is connected to server, show player on GUI
    if(Network.isServer){
        // Show players on GUI
        showPlayersOnGUI = true;
    }

    else if(Network.isClient){
        // Show players on GUI
        showPlayersOnGUI = true;
    }

}


private void StartServer(){
    Network.InitializeServer (maxNumberOfPlayers, port, false);
    MasterServer.RegisterHost(registeredGameName, "Bomba Alpha", "Test of TMB_server");
}

void OnServerInitialized(){
    Debug.Log ("Server has been initialized!");
    Debug.Log("Player " + playerCount + " connected from " + Network.player.ipAddress + ":" + Network.player.port);
    // Set server as playerBlue
    playerBlue = Network.player;
}

void OnMasterServerEvent(MasterServerEvent masterServerEvent){
    if(masterServerEvent == MasterServerEvent.RegistrationSucceeded){
        Debug.Log("Registration Successful!");
    }
}

public IEnumerator RefreshHostList(){
    Debug.Log ("Refreshing...");
    MasterServer.RequestHostList (registeredGameName);      // Get servers from MasterServer with 'our' name
    float timeStarted = Time.time;
    float timeEnd = Time.time + RefreshRequestLength;


    // Contínuelly update hostData
    while (Time.time < timeEnd) {
        hostData = MasterServer.PollHostList();                 // pull down the requested server
        yield return new WaitForEndOfFrame();

    }

    // Check if there is no servers
    if (hostData == null || hostData.Length == 0) {
        Debug.Log ("No active servers have been found");
    }

    else{
        Debug.Log(hostData.Length + " server(s) found");
    }
}


void OnPlayerConnected(NetworkPlayer player) {
    playerCount++;

    if(Network.player == player){
        Debug.Log ("Hey!");

    }

    if (playerCount == 2){
        playerPurple = player;
        Debug.Log ("I'm purple!");

    }

    // Set 2nd client as playerGreen
    else if (playerCount == 3){
        playerGreen = player;
    }

    if(Network.isServer){
        Debug.Log ("Colors are updating!");

        networkView.RPC("UpdateColors", RPCMode.Others, playerBlue, playerPurple, playerGreen, playerCount);
    }

    Debug.Log("Player " + playerCount + " connected from " + player.ipAddress + ":" + player.port);
}

void OnPlayerDisconnected(){
    playerCount--;
}


// On GUI is for testing and will not exist in the final game
public void OnGUI(){

    if (sceneManager.currentScene == 3){

        // Start server
        if(GUI.Button(new Rect(150f,100f,300f,150f), "Start new server")){
            StartServer();
        }

        // Refresh server list
        if(GUI.Button(new Rect(150f,250f,300f,150f), "Refresh server list")){
            StartCoroutine("RefreshHostList");
        }

        if (hostData != null) {
            for (int i = 0; i < hostData.Length; i++){
                if(GUI.Button(new Rect(150f ,400f + (110f * i),300f,150f), hostData[i].gameName))
                {
                    Network.Connect(hostData[i]);
                }
            }
        }

        // Show list of players connected to the server
        if (showPlayersOnGUI) {

            GUIStyle myStyle = new GUIStyle();
            myStyle.font = myFont;

            GUI.Label(new Rect(20, 700, 200, 20), ("Other players connected:"), myStyle);

            if (Network.player == playerBlue){
                GUI.Label(new Rect(20, 600, 200, 20), ("You are BLUE player"), myStyle);

                if(playerCount == 1){
                    GUI.Label(new Rect(20, 750, 200, 20), ("- none -"), myStyle);
                }
                if(playerCount >= 2){
                    GUI.Label(new Rect(20, 750, 200, 20), ("Purple player"), myStyle);
                }
                if(playerCount == 3){
                    GUI.Label(new Rect(20, 800, 200, 20), ("Green Player"), myStyle);
                }
            }

            else if (Network.player == playerPurple){
                GUI.Label(new Rect(20, 600, 200, 20), ("You are PURPLE player"), myStyle);

                if(playerCount >= 2){
                    GUI.Label(new Rect(20, 750, 200, 20), ("Blue player"), myStyle);
                }
                if(playerCount == 3){
                    GUI.Label(new Rect(20, 800, 200, 20), ("Green Player"), myStyle);
                }
            }

            else if (Network.player == playerGreen){
                GUI.Label(new Rect(20, 600, 200, 20), ("You are GREEN player"), myStyle);

                if(playerCount == 3){
                    GUI.Label(new Rect(20, 750, 200, 20), ("Blue player"), myStyle);

                    GUI.Label(new Rect(20, 800, 200, 20), ("Purple Player"), myStyle);
                }
            }
        }
    }
}



void UpdatePlayersOnNetwork(){
    if (Network.player == playerBlue) {
        Debug.Log("I'm player BLUE");
        networkView.RPC("UpdateBluePlayer", RPCMode.Others, Network.player);

    }
    if (Network.player == playerPurple) {
        Debug.Log("I'm player PURPLE");
        networkView.RPC("UpdatePurplePlayer", RPCMode.Others, Network.player);

    }
    if (Network.player == playerGreen) {
        Debug.Log("I'm player GREEN");
        networkView.RPC("UpdateGreenPlayer", RPCMode.Others, Network.player);

    }
}



// -------- RPC sends data via network --------

// Update player-color connections
[RPC]
void UpdateColors(NetworkPlayer blue, NetworkPlayer purple, NetworkPlayer green, int players){

    Debug.Log ("Colors are updated");

    playerBlue = blue;
    playerPurple = purple;
    playerGreen = green;
    playerCount = players;
    //Debug.Log ("Colors have been updated!");
}

}

谢谢

莫斯克亚尔

【问题讨论】:

    标签: networking unity3d ip client rpc


    【解决方案1】:

    没有用 C# 实现自己的 RPC 系统,您需要重写代码以“反弹”服务器上的 RPC。

    在 Unity 的网络模型中,客户端都连接到服务器,但不相互连接。客户端导致的任何状态更改都会通过服务器发送到其他客户端。

    【讨论】:

    • 感谢您的回答。那么这是否意味着我必须从客户端 1 向服务器发送一个 RPC,然后从服务器向客户端 2 发送一个新的 RPC?或者我可以使用 RPCmode.others 并发送一个 int 并用 if 句区分玩家吗?
    • 我找到了解决方案。当客户端连接到服务器时,他们会得到一个唯一的“int playerNumber”。从客户端(或服务器)发送数据时,我只使用 RPCMode.others 并设置一个与我想要接收它的玩家的 playerNumber 对应的“int player”参数。在 RPC 函数中,我只运行代码“if (player == playerInt)”
    • 是的!这与我所做的类似,尽管我使用每个玩家的 GUID,因为这在会话之间是一致的。如果您使用主服务器连接玩家,您还可以使用存储的 GUID 进行主机迁移。
    猜你喜欢
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2017-05-07
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多