Unity3D内置网络Network之授权服务器案例
2015-04-09 16:34
381 查看
新建一个场景,创建一个Plane物体命名为Ground,创建一个空物体命名为Spawn,创建一束方向光用于照亮整个场景,如图:
从Unity3D官方教程(Steal,即秘密潜如)素材包中导入主角模型和Idle动画和Walk动画,(素材地址:点击打开链接),为主角添加动画控制器,Rigidbody组件,NetworkView组件和BoxCollider组件,(脚本组件稍后讲解)并将主角保存为预制体(prefab)如图:
创建三个脚本Server,Client和PlayerCtrl,将Server脚本和Client脚本添加到主相机,如图:
将PlayerCtrl脚本添加到主角人物中,如图:
各个脚本代码如下:
Server代码:
Client代码如下:
PlayerCtrl代码如下:
将游戏发布,测试,如图:
成功,OK!
从Unity3D官方教程(Steal,即秘密潜如)素材包中导入主角模型和Idle动画和Walk动画,(素材地址:点击打开链接),为主角添加动画控制器,Rigidbody组件,NetworkView组件和BoxCollider组件,(脚本组件稍后讲解)并将主角保存为预制体(prefab)如图:
创建三个脚本Server,Client和PlayerCtrl,将Server脚本和Client脚本添加到主相机,如图:
将PlayerCtrl脚本添加到主角人物中,如图:
各个脚本代码如下:
Server代码:
using UnityEngine; using System.Collections; 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); } }
Client代码如下:
using UnityEngine; using System.Collections; 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); } }
PlayerCtrl代码如下:
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 = false; } } 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); } else if (Network.isClient) { networkView.RPC("SendInput", RPCMode.Server, currentHInput, currentVInput); } } } 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; stream.Serialize(ref pos); stream.Serialize(ref rota); stream.Serialize(ref veloc); stream.Serialize(ref angVeloc); } } [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; } } }
将游戏发布,测试,如图:
成功,OK!
相关文章推荐
- Unity3D内置网络Network之非授权服务器实例
- suse linux原创案例07: linux网络问题:Network is unreachable
- Unity3d C# 脚本学习小结 (三) 【创建网络服务器】
- 如何做一名主程之Unity3D网络游戏服务器架构设计
- Unity3d如何检测当前网络环境wifi/3G/4G,以及对服务器的Ping操作
- Unity3d检测当前网络环境wifi/3G/4G,以及对服务器的Ping操作
- Cisco网络设备搭建***服务器的成功案例
- Java基础知识强化之网络编程笔记07:TCP之服务器给客户端一个反馈案例
- Unity3d 网络编程(三)(Unity3d内置简单的网络server编制)
- Unity3D--网络(Network)
- Unity3D精简版网络游戏雏形(简单网络通信聊天和角色监视案例)
- Unity3d 网络编程(一)(Unity3d内建网络Network介绍)
- Unity3d 网络编程(三)(Unity3d内建网络简单服务器的建立)
- Unity3d 网络编程(一)(Unity3d内建网络Network介绍)
- Unity3d 网络编程(三)(Unity3d内建网络简单服务器的建立)
- 服务器群集及web服务器负载均衡Lvs-network小案例
- Unity3d 网络编程(一)(Unity3d内建网络Network介绍)
- Unity3D 多人网络游戏-客户端于服务器的同步
- System.Data.SqlClient.SqlException: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: SQL Network Interfaces, error: 26 - 定位指定的服务器/实例时出错)
- [Unity3D ARPG网络游戏编程实践] 网络连接 :unity NetWork与socket的对比(一)