NetCode for GameObject

1.属性同步

每个tick都会更新,NetworkVariable

2.Rpc同步

在方法上标记ServerRpc、ClientRpc特性,即可成为rpc方法。

ServerRpc为Client调用,Server执行,ClientRpc同理。

标记为ServerRpc的方法,会通过il修改,client下会发送RpcMessage,Server下会接受RpcMessage,并调用保存在 __rpc_func_table 里的回调方法。

以下述为例,Client调用OnFireServerRpc =》Client发送RpcMessage =》Server接受RpcMessage =》Server调用__rpc_handler_524416466 =》最终Server调用OnFireServerRpc

RpcMessage仅为NetworkObjectId、NetworkBehaviourId、RpcMethodId,以及调用时的参数

原始方法

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class NetObject : NetworkBehaviour
{
    [ServerRpc]
    public void OnFireServerRpc(int num)
    {
        Debug.Log("OnFireServerRpc: " + num);
    }

    [ClientRpc]
    public void OnFireClientRpc()
    {
        Debug.Log("OnFireClientRpc");
    }
}

经过il修改后的方法

using System;
using Unity.Netcode;
using UnityEngine;

// Token: 0x02000002 RID: 2
public class NetObject : NetworkBehaviour
{
	// Token: 0x06000004 RID: 4 RVA: 0x00002054 File Offset: 0x00000254
	[ServerRpc]
	public void OnFireServerRpc(int num)
	{
		NetworkManager networkManager = base.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
		{
			if (base.OwnerClientId != networkManager.LocalClientId)
			{
				if (networkManager.LogLevel <= LogLevel.Normal)
				{
					Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			ServerRpcParams serverRpcParams;
			FastBufferWriter writer = base.__beginSendServerRpc(524416466U, serverRpcParams, RpcDelivery.Reliable);
			BytePacker.WriteValueBitPacked(writer, num);
			base.__endSendServerRpc(ref writer, 524416466U, serverRpcParams, RpcDelivery.Reliable);
		}
		if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Server || (!networkManager.IsServer && !networkManager.IsHost))
		{
			return;
		}
		Debug.Log("OnFireServerRpc: " + num.ToString());
	}

	// Token: 0x06000005 RID: 5 RVA: 0x00002188 File Offset: 0x00000388
	[ClientRpc]
	public void OnFireClientRpc()
	{
		NetworkManager networkManager = base.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams clientRpcParams;
			FastBufferWriter fastBufferWriter = base.__beginSendClientRpc(919245642U, clientRpcParams, RpcDelivery.Reliable);
			base.__endSendClientRpc(ref fastBufferWriter, 919245642U, clientRpcParams, RpcDelivery.Reliable);
		}
		if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost))
		{
			return;
		}
		Debug.Log("OnFireClientRpc");
	}

	// Token: 0x06000007 RID: 7 RVA: 0x00002264 File Offset: 0x00000464
	// Note: this type is marked as 'beforefieldinit'.
	static NetObject()
	{
		NetworkManager.__rpc_func_table.Add(524416466U, new NetworkManager.RpcReceiveHandler(NetObject.__rpc_handler_524416466));
		NetworkManager.__rpc_func_table.Add(919245642U, new NetworkManager.RpcReceiveHandler(NetObject.__rpc_handler_919245642));
		NetworkManager.__rpc_name_table.Add(524416466U, "OnFireServerRpc");
		NetworkManager.__rpc_name_table.Add(919245642U, "OnFireClientRpc");
	}

	// Token: 0x06000008 RID: 8 RVA: 0x000022D0 File Offset: 0x000004D0
	private static void __rpc_handler_524416466(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
		{
			if (networkManager.LogLevel <= LogLevel.Normal)
			{
				Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
			}
			return;
		}
		int num;
		ByteUnpacker.ReadValueBitPacked(reader, out num);
		target.__rpc_exec_stage = NetworkBehaviour.__RpcExecStage.Server;
		((NetObject)target).OnFireServerRpc(num);
		target.__rpc_exec_stage = NetworkBehaviour.__RpcExecStage.None;
	}

	// Token: 0x06000009 RID: 9 RVA: 0x00002380 File Offset: 0x00000580
	private static void __rpc_handler_919245642(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		target.__rpc_exec_stage = NetworkBehaviour.__RpcExecStage.Client;
		((NetObject)target).OnFireClientRpc();
		target.__rpc_exec_stage = NetworkBehaviour.__RpcExecStage.None;
	}

	// Token: 0x0600000A RID: 10 RVA: 0x000023D1 File Offset: 0x000005D1
	internal override string __getTypeName()
	{
		return "NetObject";
	}
}