问题描述
因此,我已经基于现有协议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 (将#修改为@)