網絡子產品優化方向
網絡優化的目的是讓網絡包更小,響應更及時,消耗更少流量,不卡主線程。
減少無用字段
網絡包中通常包含了很多資訊,諸如角色位置,朝向,狀态等。
如果是2.5D遊戲,則位置z分量可以棄掉;朝向隻在xz平面上,是以隻需要發送RotationY。
通過這種減少無用字段,可以一定程度上降低網絡包大小。
降低字段精度
能用byte的不用int。
通常邏輯裡的很多資訊都是4位元組,包括角色位置,朝向,技能或Buff資訊等。但很多時候,這些資訊不可能達到4位元組數的最大值,可以壓縮至2位元組甚至1位元組。
比如,同樣是位置,場景的尺寸通常在2位元組數的表示範圍内(-32512~32512),可以将位置的x/y/z壓縮至2位元組發送。同樣地,朝向RotationY可以2位元組表示。
2.5d遊戲用byte轉vector3節省網絡流量
用戶端給伺服器,傳輸的是polynav2d尋路的角度,傳輸的是個byte值,因為角度360,即使隻傳輸一半180,隻損失2度的精度,但是可以隻傳輸byte
伺服器給用戶端,需要一個gameobject進行轉換,設定的是avatar相對于actor的角度
//vector2轉伺服器角度,相當于一個優化,傳輸byte,
public static DIR_TYPE CalculateDirection(Vector2 dir)
{
float angle = Vector2.Angle(dir, Vector2.up);
if (dir.x < 0)
{
angle = 360 - angle;
}
byte bdir = (byte)Mathf.RoundToInt(angle / 2);
if (bdir == (int)DIR_TYPE.DIR_DEFALT) bdir = (byte)DIR_TYPE.DIR_NORTH;
return (DIR_TYPE)bdir;
}
//角度換算,隻為avatar,把人物的朝向角度轉換為 avatar相對于父物體的偏轉,先自身繞y軸轉dir*2角度,再以Vector3.left為軸,轉90度
private static Dictionary<int, Vector3> eulerDict = new Dictionary<int, Vector3>();
public static Vector3 GetEuler(DIR_TYPE dir)
{
int _dir = (int)dir;
Vector3 val;
if (eulerDict.TryGetValue(_dir, out val))
{
return val;
}
else
{
if (dir == DIR_TYPE.DIR_NONE)
{
eulerDict[_dir] = Vector3.zero;
return Vector3.zero;
}
//通過gameobject中轉,把角度值轉換為向量
GameObject tempObj = new GameObject();
Transform trans = tempObj.transform;
trans.position = Vector3.zero;
trans.localEulerAngles = new Vector3(0, _dir * 2, 0);
trans.RotateAround(Vector3.zero, Vector3.left, 90);
eulerDict.Add(_dir, trans.localEulerAngles);
GameObject.Destroy(tempObj);
return eulerDict[_dir];
}
}
避免重複發送
遊戲網絡子產品須有效限制部分協定在短時間内重複發送,例如玩家在短時間内按了很多次抽獎按鈕。
是以需要一種機制來限制。比如可以在網絡協定定義時,加個标記,表明該協定不能在某個時間段内重複發送。