如何解决我如何正确处理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 举报,一经查实,本站将立刻删除。