Unity3d网络总结(一) NetWork组件使用
学习Unity3d的过程中,经常上网查阅各位大牛的博客,受益匪浅,从今天开始写自己在学习过程中遇到的问题,总结归纳下来,方便日后复习
这两天在学习Unity的网络模块,今天先总结Unity自带的Network组件相关使用方法
1.网络管理物体
搭建网络,需要先创建一个空物体用来添加网络管理组件,首先要给空物体添加以下两个组件
注意事项: 1. OffLine Scene代表客户端连接服务器前,等待的场景(游戏大厅)
. OnLine Scene代表客户端连接服务器后的场景 (游戏场景)
2.Spawn Info 服务器卵生信息 : 把网络预设体(必须挂有网络组件) 拖入PlayerPrefab , 服务器会把游戏对象孪生到所有连接的客户端中
二.游戏对象
1.Network Identity
游戏对象(网络预设体)需要挂Network Identity组件,该组件是网络的核心,由服务器Spwan(卵生)的物体都必须具备,该组件在卵生的时候会自动分配assetID和权限
注意事项:1.ServerOnly 勾选后物体只在服务器中存在
2.Local Player Authority勾选后在客户端中存在
2.实现状态同步
游戏对象的控制脚本需要继承NetWorkBehaviour组件(依赖于NetWorkIdentity),用来实现RPC技术和状态同步属性.
1.Transform同步
这个组件负责玩家对象在客户端发出移动指令后,把该玩家的移动同步到所有客户端中
注意事项:1.Net Work Send Rate 表示同步Transform的频率
2.Transform Synv Mode 表示同步的模式,可以选择同步刚体组件,角色控制器等
然后在控制脚本编写代码
public class ControlMove : NetworkBehaviour {
void Update() {
if (!isLocalPlayer) //判断是否是本地客户端 {
return;
}
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
if (x != 0 || y != 0)
{
transform.position += new Vector3(x, 0, y);
}
这里需要注意的有两点 1.所有网络控制脚本必须要继承 NetWorkBehaviour
2.在Update里需要先判断是否是本地客户端,不是的话Return~!!! 如果没有这个判断条件,在客户端发出指令,网络里所有的客户端都会执行
2.发射子弹与减血的同步
经过上边的步骤,已经可以实现物体在网络里的移动,但我们想要实现在网络里发射子弹,受到攻击后还要减血,这些指令都需要在服务器上执行,先来看一下NetWorkBehaviour的常用特性
[SyncVar] 用于标识序列化变量,实现变量同步 例: (把Hp标识,就可以实现同步减血)
[Client] 表示只能在客户端调用
[ClientCallBack] 表示客户端执行的回调
[Command] 表示客户端向服务端发送的命令,在服务端执行
[ClientPrc] 表示服务端向客户端发送的命令,在客户端执行
直接来看代码如何使用:
//将血量设置为网络同步变量 [SyncVar]
float hp = 100;
public Slider slider; //显示血量的血条
public GameObject bullet; //子弹预设体
void Start () {
ClientScene.RegisterPrefab(bullet); //在场景注册预设体 }
void Update () {
// 2.将血量的值赋给slider
slider.value = hp / 100f;
if (!isLocalPlayer)
{
return;
}
if (Input.GetKeyDown(KeyCode.Q))
{
CmdReduceHp();
}
if (Input.GetKeyDown(KeyCode.T))
{
CmdFire();
}
}
//减血的方法 标识为Command由服务器执行
//前缀必须是Cmd 开头 [Command]
public void CmdReduceHp()
{
hp -= 10;
} //发射子弹的方法 [Command]
public void CmdFire()
{
GameObject a= Instantiate(bullet, transform.position+transform.right, Quaternion.identity);
a.GetComponent<Rigidbody>().AddForce(transform.right*100); //给子弹添加向右的力
NetworkServer.Spawn(a); //由服务器卵生给连接的客户端
}
注意事项:1.网络预设体需要先在客户端场景里注册一下,才能正常产生
2.hp赋值给Slider要写在判断是否是本地客户端前,血条才会正常同步显示
3.Command修饰的方法,由客户端发起,服务端执行,方法名前必须加Cmd
4.监听键盘事件的Iput.GetKeyDown要放在Update里,不能放在Cmd方法里!!! (此时方法由服务器调用,无法监听键盘事件)
3.动画的同步
要实现游戏对象的动画同步,还需要添加一个网络组件,并给组件指定Animator,并勾选Animator里包含的动画.
动画同步需要注意一点,过度条件是Trigger时需要由客户端发起指令,在服务端执行,再分发给各个客户端执行,其他条件正常.
这里Animator的两个动画,attack01条件是bool,attack02条件是Trigger ,代码如下:
Animator ani;
void Start()
{
ani = GetComponent<Animator>();
}
void Update () {
if (Input.GetKeyDown(KeyCode.Q))
{
ani.SetBool("attack01", !ani.GetBool("attack01"));
}
if (Input.GetKeyDown(KeyCode.E))
{
CmdAttack02();
}
}
[Command] //服务器执行
void CmdAttack02()
{
RpcPlayTrigger();
}
[ClientRpc] //由服务器端调用,在客户端执行
void RpcPlayTrigger()
{
ani.SetTrigger("attack02");
}
Unity3d网络总结(二)使用NetWorking代码搭建简单的网络模块
上一篇文章(http://www.cnblogs.com/dabaimifan/p/7212615.html)介绍了通过给物体添加NetWorking相关组件实现简单的搭建一个网络,本文通过C#代码搭建一个简单的网路,详细解释会在代码里注释,供新手学习使用
首先,引入UnityEngine下的NetWorking命名空间,并初始化相关对象,提前创建好预设体并放入Resources文件夹下,这里需要注意的是在Start里调用方法让程序保持在后台运行,不然客户端会连接不上服务器(后台),
public class NetManager : MonoBehaviour {
//创建客户端 NetworkClient MyClient;
//创建预设体 网络对象 GameObject playerPre;
void Start ()
{
//保持程序后台运行
Application.runInBackground = true;
playerPre = Resources.Load("Player") as GameObject;
//初始化客户端
MyClient = new NetworkClient();
}
然 后写 创建服务器的方法
//创建服务器的方法
public void InitServerAction()
{
if (!NetworkServer.active)
{
//创键并开启服务器,服务器开始监听
// 默认ip地址 为127.0.0.1
NetworkServer.Listen("127.0.0.1", 1345);
Debug.Log("服务器已经开启");
//给服务器注册回调方法(ServerAddPlayerCallback) NetworkServer.RegisterHandler(MsgType.AddPlayer, ServerAddPlayerCallback);
//将服务器也初始化 为一个客户端
MyClient = ClientScene.ConnectLocalServer();
//注册客户端连接之后的回调方法(ClientConnectServerCallback) MyClient.RegisterHandler(MsgType.Connect, ClientConnectServerCallback);
}
}
写服务器添加玩家后的回调方法(ServerAddPlayerCallback) 与客户端连接之后的回调方法(ClientConnectServerCallback):
//服务器接收客户端发送的添加游戏玩家之后执行的回调方法
void ServerAddPlayerCallback(NetworkMessage msg)
{
//创建一个游戏对象
GameObject player= Instantiate(playerPre,new Vector3(0,0,0),Quaternion.identity);
//将创建的网络对象的权限赋值给客户端
NetworkServer.AddPlayerForConnection(msg.conn, player,31);
//将该玩家的对象卵生到所有连接服务器的客户端 NetworkServer.Spawn(player);
}//客户端连接之后的回调方法