Mirror是一个简单高效的开源的Unity多人游戏网络框架。
在这里按照油管dalao的教学流程,与官方文档学习常用的API及操作。
https://mirror-networking.gitbook.io/docs
API
Mirror提供了一个特性SyncVar
来进行数据同步,
它的核心逻辑就是,当服务器
的场景中的一个SyncVar
的值发生变化时,就同步给其它所有客户端
。
基本的用法是在需要进行同步的变量前编辑特性标签:
[SyncVar]
Color colorNeededToSynchronize;
其中经常定义hook
参数,
当数据发生变化时,就自动调用一个自定义的函数MySetColor
函数,
注意这个函数只会在客户端调用(当然主机也运行了一个客户端)
而MySetColor
的声明如下,提供了新旧值的访问,
注意新旧值的类型与监听的数值的类型一致:
[SyncVar(hook = nameof(MySetColor))]
void MySetColor(Color oldColor, Color newColor)
在编写代码的时候要注意,使用此特性标注的变量,只应该在服务器上对此变量进行更改
而通过hook在客户端作用此更改
使用
接下来用一个例子展示此API:
为上一节写的Cube添加一个控制脚本。
注意脚本继承自NetworkBehaviour
,命名空间using Mirror;
以便获取到Mirror的API:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class PlayerController : NetworkBehaviour
{
[SyncVar(hook = nameof(ColorChanged))]
Color PlayerColor = Color.white;
Rigidbody rb;
MaterialPropertyBlock prop;
void ColorChanged(Color oldColor, Color newColor){
Debug.Log("Color Changed");
prop.SetColor("_Color" ,newColor);
GetComponent<Renderer>().SetPropertyBlock(prop);
}
private void Start() {
rb = GetComponent<Rigidbody>();
prop = new MaterialPropertyBlock();
GetComponent<Renderer>().GetPropertyBlock(prop);
}
float duringTimer = 0f;
private void Update() {
rb.velocity = new Vector3(0,0,0);
if(isServer){
if(duringTimer < 2f){
duringTimer+=Time.deltaTime;
}else{
duringTimer = 0f;
PlayerColor = PlayerColor==Color.white?Color.black:Color.white;
}
}
}
}
这一段代码的功能就是,每隔2秒改变一次玩家的颜色。
尤其注意代码中一个API isServer
,
这说明下面这段代码只会在服务器上运行,而客户端是不会运行的,
if(isServer){
if(duringTimer < 2f){
duringTimer+=Time.deltaTime;
}else{
duringTimer = 0f;
PlayerColor = PlayerColor==Color.white?Color.black:Color.white;
}
}
整体的逻辑就是:
服务器上的每一个主角物体,
每两秒改变一次PlayerColor
的值,
然后服务器通过SyncVar
将改变前后的值发送给每一个客户端,
接下来每一个客户端对应的物体调用hook
函数也就是ColorChanged(Color oldColor, Color newColor)
函数,
将值改变带来的效果作用到自己的场景中。
测试
打开两个游戏,其中一个做客户端,一个做主机(服务器+客户端)
可以看到各自的主角颜色随着时间进行变化。
注意hook函数不会在服务器上调用
打开两个游戏,其中一个做客户端,一个只做服务器
可以看到,虽然我们清楚服务器中的PlayerColor
的值肯定变化了,
但是由于服务器没有执行hook函数,因此服务器上看到的这个实体颜色没有变化。
(上一个测试能看到都有变化,是因为上一个测试服务器上也有一个客户端,所有看到的本质上还是客户端而不是服务器)