我如何正确处理Internal_CloneSingle只能从主线程调用

问题描述

因此,我已经基于现有协议TCP开发了自己的网络协议。

我现在终于可以在我的游戏中实现它了,这根本不是一个复杂的游戏。当客户端连接到服务器时,它要做的就是在播放器中生成

我现在面临的问题是当我尝试致电Instantiate();时会引发异常:

UnityEngine.UnityException: Internal_Clonesingle can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers,instead move initialization code to the Awake or Start function.
  at (wrapper managed-to-native) UnityEngine.Object.Internal_Clonesingle(UnityEngine.Object)
  at UnityEngine.Object.Instantiate[T] (T original) [0x00017] in C:\buildslave\unity\build\Runtime\Export\UnityEngineObject.bindings.cs:275 
  at GameManager.SpawnPlayer (system.int32 id,System.String username) [0x00023] in C:\Users\user\Documents\Astaria\Assets\Scripts\GameManager.cs:37 
  at ClientHandleData.SpawnPlayer (System.Byte[] data) [0x000a9] in C:\Users\user\Documents\Astaria\Assets\Scripts\ClientHandleData.cs:166 
  at ClientHandleData.HandlePacket (System.Byte[] data) [0x00031] in C:\Users\user\Documents\Astaria\Assets\Scripts\ClientHandleData.cs:95 
  at ClientHandleData.HandleData (System.Byte[] data) [0x000ef] in C:\Users\user\Documents\Astaria\Assets\Scripts\ClientHandleData.cs:66 
  at GameNet.OnReceive (System.IAsyncResult ar) [0x0003c] in C:\Users\user\Documents\Astaria\Assets\Scripts\GameNet.cs:62 
UnityEngine.Debug:LogError(Object)
GameNet:OnReceive(IAsyncResult) (at Assets/Scripts/GameNet.cs:70)
System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

我的场景中有一个名为GameManager的空对象,在其中我已经将GameManager脚本附加到了该对象上,

public class GameManager : MonoBehavIoUr
{
    public static GameManager instance;
    public static Dictionary<int,Client> players = new Dictionary<int,Client>();
    public GameObject localPlayerPrefab;
    public GameObject playerPrefab;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(this);
        }
    }

    public void SpawnPlayer(int id,string username)
    {

        //Instantiate can only be called from the main thread..
        GameObject _player;
        if (id == Client.instance.clientId)
            _player = Instantiate(localPlayerPrefab);
        else
            _player = Instantiate(playerPrefab);

        players.Add(id,_player.GetComponent<Client>());
        Debug.Log($"PLAYER WITH THE ID: {id} HAS CONNECTED!");
    }
}

然后从我的ClientHandleData.cs

调用函数
private void SpawnPlayer(byte[] data)
{
    Packet packet = new Packet();
    packet.WriteBytes(data);
    var clientId = packet.ReadInt();
    var username = packet.ReadString();
    
    //Spawn the connected player on my screen
    GameManager.instance.SpawnPlayer(clientId,username);
}

哪个是在该类顶部的字典中定义的

public delegate void Packet_(byte[] data);
private Dictionary<byte,Packet_> packets;
public void InitializePackets()
{
    Debug.Log("Initializing Network Packets..");
    packets = new Dictionary<byte,Packet_>();
    packets.Add((byte)GameOpCodes.PlayerData,SpawnPlayer);

}

InitializePackets调用函数Client.cs 看起来像这样

public class Client : MonoBehavIoUr
{
    public static ClientHandleData HandleData = new ClientHandleData();
    public static GameNet client;
    public string username;

    public static Client instance;

    private void Awake()
    {
        instance = this;
    }

    private void Start()
    {
        HandleData.InitializePackets();
        client = new GameNet();
        client.ConnectToServer();
    }

}

客户端从GameNet.cs接收数据的方式来自OnReceive套接字回调

然后运行此

Client.HandleData.HandleData(myBytes);

这就是将它们绑在一起的方式。

为什么会引发异常,我该如何正确处理?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)