Unity3D - 无法调用RPC函数,因为networkView不存在

时间:2014-12-23 21:13:29

标签: c# unity3d client-server rpc

所以,我正在开发一个Unity项目,我需要在其中实现客户端/服务器功能。

客户端有自己的“场景”,服务器也有自己的场景。服务器代码和networkView将附加到其场景中的主摄像头。代码如下:

using UnityEngine;
using System.Collections;
using System.Net;
using System.Collections.Generic;

public class NetworkManagerCS : MonoBehaviour { 
    public int loadlevel;
    public int connectPort = 25000;
    public string hostname;
    public string GameName = "Historical Grounds";
    private bool refreshing;
    private HostData[] hostData;

    private Dictionary<string, string> playerList = new Dictionary<string, string>();

    string textToEdit = "Type text here";

    // This is for debuggin purposes only!! Will be deprecated
    public void OnGUI() {
        if (Network.peerType == NetworkPeerType.Disconnected) {
            GUILayout.Label("Connection status: Disconnected");

            GUILayout.BeginVertical();
            if (GUILayout.Button("Connect as client"))
            {
                ConnectToServer();  
            }

            if (GUILayout.Button("Start Server"))
            {
                Network.InitializeServer(4, connectPort, true);
                MasterServer.RegisterHost(GameName, "Tutorial Game", "This is a turn based shooter");
                //Network.Instantiate(camera, transform.position, transform.rotation, 0);
            }
            GUILayout.EndVertical();
        }
        else
        {
            // Connecting...
            if (Network.peerType == NetworkPeerType.Connecting)
            {       
                GUILayout.Label("Connection status: Connecting");   
            }

            // Clientside buttons
            else if (Network.peerType == NetworkPeerType.Client)
            {           
                GUILayout.Label("Connection status: Client!");
                GUILayout.Label("Ping to server: " + Network.GetAveragePing(Network.connections[0]));

                textToEdit = GUILayout.TextField(textToEdit, 25);

                if( GUILayout.Button("Attack Server")) {
                    float[] args = new float[3];
                    args[0] = float.Parse(textToEdit);
                    args[1] = 4.123f;
                    args[2] = 23.2f;
                    networkView.RPC("AttackServer", RPCMode.AllBuffered, args);
                }
            }

            // Serverside
            else if (Network.peerType == NetworkPeerType.Server)
            {
                GUILayout.Label("Connection status: Server!");
                GUILayout.Label("Hostname is:" + System.Net.Dns.GetHostName() );
                GUILayout.Label("Connections: " + Network.connections.Length);          
            }

            // Disconnect happens in both server and client
            if (GUILayout.Button("Disconnect"))
            {
                Network.Disconnect(200);
            }
        }


    }


    // AKA While(true)
    public void Update() {

        /*
         * If we have a "refreshing" flag, then we poll the master server
         * until we get a length larger than 0. Then, we connect to server.
         */
        if(refreshing) {
                if (MasterServer.PollHostList().Length > 0) {
                refreshing = false;
                Debug.Log(MasterServer.PollHostList().Length);  
                hostData = MasterServer.PollHostList();
                ConnectToServer();
            }
        }
    }

    /*
     * If hostData does not exist, refresh
     * Otherwise, connect to the first game you see.
     * 
     * This is the "dumb" approach, but I assume that there are not going to be more
     * than one game running at a time... 
     */
    public void ConnectToServer() {
        if (hostData == null) {
            MasterServer.RequestHostList(GameName);
            refreshing = true;
        } else {
            Network.Connect(hostData[0]);
        }
    }

    /*
     * Keeping this here so that I will remember to add system info sends
     */
    public void OnConnectedToServer()
    {       
        //Application.LoadLevel(loadlevel);
    }

    /*
     * DEBUG FUNCTION!!! This will be called when someone disconnected from
     * the msater server
     */
    public void OnDisconnectedFromServer(NetworkDisconnection info) {
        if (info == NetworkDisconnection.LostConnection) {
            if (Network.peerType == NetworkPeerType.Client) {
                Debug.Log ("Client has lost connection");
            } else {
                Debug.Log ("Server has lost connection");
            }
        } else {
            Debug.Log ("Disconnected Successfully");
        }
    }

    /*
     * Lawl, fail.... 
     */
    public void OnFailedToConnect(NetworkConnectionError error)
    {
        Debug.LogError(error.ToString());
        Network.Disconnect(400);
    }

    /*
     * The purpose of this function is to assign a monster to a player
     * Once all monsters have been assigned, I guess the Update() function will
     * RPC to the phones that they are ready to play.
     */
    public void OnPlayerConnected(NetworkPlayer player) {
        networkView.RPC("assignPlayer", RPCMode.All, player);
    }

    /*
     * Not interesting... Server initialized..
     */
    public void OnServerInitialized()
    {
        //Application.LoadLevel(loadlevel);
        Debug.Log("Server Started");
    }

    void OnMasterServerEvent(MasterServerEvent msg) {
        if (msg == MasterServerEvent.RegistrationSucceeded){
            Debug.Log("Registered Server!");
            Network.isMessageQueueRunning = true;
        }
    }

    /*void OnPlayerDisconnected(NetworkPlayer player) {
        Transform playerTransform = GameObject.Find("Player_" + player.guid);
        if (playerTransform != null) {
            Destroy (playerTransform.gameObject);
        }

        Network.RemoveRPCs(player);
        Network.DestroyPlayerObjects(player);
    }*/


    // Testers - Should deprecate
    /*[RPC]
    public void AttackServer(float[] args) {
        foreach (float value in args) {
        Debug.Log ("Server is under attack with force " + value);
        }
    }*/

    // RPC's Server Side
    [RPC]
    public void sendLifeCount(NetworkPlayer player) {
        Debug.Log("Sending Life Count to " + player.ipAddress);
    }

    [RPC]
    public void isDead(NetworkPlayer player) {
        Debug.Log("You're dead! " + player.ipAddress);
    }

    [RPC]
    public void unlockScreen(NetworkPlayer player) {
        Debug.Log("Unlocking screen for.." + player.ipAddress);
    }

    [RPC]
    public void assignPlayer(NetworkPlayer player) {
        playerList.Add(player.guid, "1");
        Debug.Log(playerList[player.guid]);
        Debug.Log("Player connected from: " + player.ipAddress + ":" + player.port);
        Debug.Log("The player on IP " + player.ipAddress + " has been assigned the x monster");
    }

    public Object networkprefab { get; set; }
}

另一方面,客户端在另一个场景中,其代码在这里:(由于问题没有附加networkView ......

    using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Text.RegularExpressions;

public center code herelass InputField : MonoBehaviour {


// Client-server bullshit
private int loadlevel;
private HostData[] hostData;
private bool refreshing;
public string GameName = "Historical Grounds";

private bool connected;
public Canvas mainCanvas;
public Canvas gameCanvas;
public Button Connect;
public Text nameFieldInput;
public Text nameField;
public Text Error;
private string userName;

void Awake()
{
    if (connected)
    {
        mainCanvas.enabled = false;
        gameCanvas.enabled = true;
    }
    else {
        mainCanvas.enabled = true;
        gameCanvas.enabled = false;
    }
    Debug.Log(connected);
}

public void Update()
{

    /*
     * If we have a "refreshing" flag, then we poll the master server
     * until we get a length larger than 0. Then, we connect to server.
     */
    if (refreshing)
    {
        if (MasterServer.PollHostList().Length > 0)
        {
            refreshing = false;
            Debug.Log(MasterServer.PollHostList().Length);
            hostData = MasterServer.PollHostList();
            ConnectToServer();
        }
    }
}

public void onConnect()
{
    ConnectToServer();
}

public void OnConnectedToServer()
{
    var viewID = Network.AllocateViewID();
}

public void ConnectToServer()
{
    if (hostData == null)
    {
        MasterServer.RequestHostList(GameName);
        refreshing = true;
    }
    else
    {
        if (Switch())
        {
            connected = true;
            Network.Connect(hostData[0]);
        }
    }
}

private bool Switch(){
    userName = nameFieldInput.text;
    Debug.Log(userName);
    if(Validate(userName)){
        nameField.text = userName;
        mainCanvas.enabled = false;
        gameCanvas.enabled = true;
        connected = true;
        return true;
    } else {
        Error.text = "Invalid name!" + "\n" + "Name should be 2-8 characters and start with a capital letter";
        return false;
    }
}

private bool Validate(string input){
    string pattern = @"^[A-Z][A-Za-z0-9][A-Za-z0-9]+";
    Match match = Regex.Match(input, pattern);
    if (match.Success)
    {
        return true;
    }
    return false;
}

public void OnDisconnectedFromServer(NetworkDisconnection info)
{
    if (info == NetworkDisconnection.LostConnection)
    {
        if (Network.peerType == NetworkPeerType.Client)
        {
            Debug.Log("Client has lost connection");
        }
        else
        {
            Debug.Log("Server has lost connection");
        }
    }
    else
    {
        Debug.Log("Disconnected Successfully");
    }
}

public void OnFailedToConnect(NetworkConnectionError error)
{
    Debug.LogError(error.ToString());
    Debug.Log("FAIL!");
}

public void OnDisconnectedFromServer()
{
    connected = false;
    Debug.Log("Lawl Disconnected");
}

}

TL; DR:我在尝试从客户端向服务器调用RPC(fire())时不断收到该错误消息。谁知道为什么?

谢谢!

0 个答案:

没有答案