NetWork学习小结

1.首先是服务器代码:

using UnityEngine;
using System.Collections;

/// <summary>
/// 1.服务器函数实现功能
/// 2.该函数里的一些功能函数是系统自己在条件满足的时候,自己调用,不需要我们通过代码来调用,我们只
/// 需要把功能添加好就可以了,简单的说相当远OnUpdate一样,都是系统自己调用的,不受我们支配
/// 例如OnServerInitialized()、OnPlayerConnected()、OnPlayerDisconnected()这写都是的
/// 3.服务端只画出Create the server,但前提是服务器还没有创建
/// </summary>
public class Server : MonoBehaviour
{
    private int connectionNum = 15;
    private int listenPort = 10000;
    private bool useNAT = false;

    public GameObject playerPrefab;            //新建的目标对象
    public GameObject spawn;                   //玩家产生的位置
    public ArrayList list = new ArrayList();   //用于存储玩家的PlayerCtrl脚本组件

    void OnGUI()
    {
        switch (Network.peerType)
        {
            case NetworkPeerType.Disconnected:
                if (GUI.Button(new Rect(10, 10, 200, 40), "Create the server"))
                {
                    Network.incomingPassword = "UnityNetwork";
                    Network.InitializeServer(connectionNum, listenPort, useNAT);
                }
                break;
            case NetworkPeerType.Server:
                GUILayout.Label("Initailize server is successful");
                GUILayout.Label("There are the clients that connecte to the server");
                for (int i = 0; i < Network.connections.Length; i++)
                {
                    GUILayout.Label("client's IP is: " + Network.connections[i].ipAddress);
                    GUILayout.Label("client's Port is: " + Network.connections[i].port);
                }
                if (GUILayout.Button("close the connection"))
                {
                    Network.Disconnect(200);
                }
                break;
            default:
                break;
        }
    }

    //实例化服务器玩家
    void OnServerInitialized()                   //创建服务器的时候执行,也是服务端调用,服务器会自动执行
    {
        InitPlayer(Network.player);
    }

    //实例化客户端玩家
    public void OnPlayerConnected(NetworkPlayer player)      //客户端连接服务器的时候执行,也是服务端调用,服务器会自动执行
    {
        InitPlayer(player);
    }

    //玩家断开连接时
    public void OnPlayerDisconnected(NetworkPlayer player)
    {
        foreach (PlayerCtrl pctrl in list)
        {
            if (pctrl.ownPlayer == player)
            {
                Network.RemoveRPCs(pctrl.gameObject.networkView.viewID);
                Network.Destroy(pctrl.gameObject);
                list.Remove(pctrl);
                break;
            }
        }

        int playerID = int.Parse(player.ToString());
        Network.RemoveRPCs(player, playerID);
        Network.RemoveRPCs(player);
        Network.DestroyPlayerObjects(player);   //服务端调用
    }

    void InitPlayer(NetworkPlayer player)
    {
        int playerID = int.Parse(player.ToString());          //获取玩家ID

        GameObject goPlayer = Network.Instantiate(playerPrefab, spawn.transform.position, spawn.transform.rotation, playerID) as GameObject;

        list.Add(goPlayer.GetComponent<PlayerCtrl>());

        //设置每个玩家对象的NetworkPlayer标示
        goPlayer.GetComponent<NetworkView>().RPC("SetPlayer", RPCMode.AllBuffered, player);//第二个参数是把player信息放在缓冲池中,这样要是有新的玩家来了,可以看到之前玩家的状态信息
    }

}

 

2.客户端代码

using UnityEngine;
using System.Collections;

/// <summary>
/// 客户端只在ui上面画connecte to the server按钮当按钮点击的时候按钮会改变成为Close the connection按钮,
/// 给玩家很好的体验
/// </summary>
public class Client : MonoBehaviour
{
    private string remoteIP = "127.0.0.1";
    private int remotePort = 10000;
    private string passWord = "UnityNetwork";

    void OnGUI()
    {
        switch (Network.peerType)
        {
            case NetworkPeerType.Disconnected:
                if (GUI.Button(new Rect(Screen.width / 2 + 10, 10, 200, 40), "connecte to the server"))
                {
                    Network.Connect(remoteIP, remotePort, passWord);
                }
                break;
            case NetworkPeerType.Connecting:
                GUI.Label(new Rect(Screen.width / 2 + 10, 10, 200, 40), "connecting....");
                break;
            case NetworkPeerType.Client:
                GUI.Label(new Rect(Screen.width / 2 + 10, 10, 200, 40), "connection is successful");
                if (GUI.Button(new Rect(Screen.width / 2 + 10, 60, 200, 40), "Close the connection"))
                {
                    Network.Disconnect(200);
                }
                break;
            default:
                break;
        }
    }

    public void OnDisconnectedFromServer(NetworkDisconnection info)
    {
        Application.LoadLevel(Application.loadedLevel);
    }
}

3.人物控制脚本

using UnityEngine;
using System.Collections;

public class PlayerCtrl : MonoBehaviour
{
    public NetworkPlayer ownPlayer;                //每个玩家的NetworkPlayer标示

    public float rotationSpeed = 15f;              //玩家转身速度

    private Animator anim;

    //客户端存储的输入值
    private float clientHInput = 0f;
    private float clientVInput = 0f;

    //服务端存储的输入值
    private float serverHInput = 0f;
    private float serverVInput = 0f;

    //游戏对象当前状态
    private float currentHInput = 0f;
    private float currentVInput = 0f;

    void Awake()
    {
        anim = GetComponent<Animator>();
        if (Network.isClient)
        {
            enabled = true;//当是客户端的时候,不能对服务器端的人控制
        }
    }

    void Update()
    {
        if (Network.player == ownPlayer)
        {
            currentHInput = Input.GetAxis("Horizontal");
            currentVInput = Input.GetAxis("Vertical");

            if (currentHInput != clientHInput || currentVInput != clientVInput)
            {
                clientVInput = currentVInput;
                clientHInput = currentHInput;

                if (Network.isServer) //是否是服务器
                {
                    SendInput(currentHInput, currentVInput);//改变serverHInput,serverVInput的值,来实现移动
                }
                else if (Network.isClient) //是否是客户端
                    {
                        networkView.RPC("SendInput", RPCMode.Server, currentHInput, currentVInput);//改变serverHInput,serverVInput的值,来实现移动
                    }
            }
        }

        if (Network.isServer) //最终服务器和客户端的玩家移动都是通过这个来实现的,及把数据传给服务器
        {
            if (serverHInput != 0 || serverVInput != 0)
            {
                WalkState(serverHInput, serverVInput);
            }
            else
            {
                IdleState();//服务器上显示停止运动
                networkView.RPC("SetFloat", RPCMode.OthersBuffered, 0f);//客户端上显示停止运动
            }
        }
    }

    void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    {
        if (stream.isWriting)                //发送数据
        {
            Vector3 pos = rigidbody.position;
            Quaternion rota = rigidbody.rotation;
            Vector3 veloc = rigidbody.velocity;
            Vector3 angVeloc = rigidbody.angularVelocity;

            stream.Serialize(ref pos);
            stream.Serialize(ref rota);
            stream.Serialize(ref veloc);
            stream.Serialize(ref angVeloc);
        }
        else                              //接受数据
        {
            Vector3 pos = Vector3.zero;
            Quaternion rota = Quaternion.identity;
            Vector3 veloc = Vector3.zero;
            Vector3 angVeloc = Vector3.zero;
        }
    }

    [RPC]
    void SendInput(float currentHInput, float currentVInput)
    {
        serverHInput = currentHInput;
        serverVInput = currentVInput;
    }

    void WalkState(float serverHInput, float serverVInput)
    {
        anim.SetFloat("Speed", 0.2f);//服务器上运动
        networkView.RPC("SetFloat", RPCMode.OthersBuffered, 0.2f);//客户端上显示运动

        Vector3 dir = new Vector3(serverHInput, 0, serverVInput);
        Quaternion look = Quaternion.LookRotation(dir, transform.up);
        transform.rotation = Quaternion.Lerp(transform.rotation, look, rotationSpeed * Time.deltaTime);
    }

    [RPC]
    void IdleState()
    {
        anim.SetFloat("Speed", 0f);
    }

    [RPC]
    void SetFloat(float speed)
    {
        anim.SetFloat("Speed", speed);
    }

    [RPC]
    void SetPlayer(NetworkPlayer player)
    {
        ownPlayer = player;
        if (player == Network.player)
        {
            enabled = true;
        }
    }
}

posted @ 2015-04-27 09:55  小歪歪Frank  阅读(313)  评论(0)    收藏  举报