我正在使用Unity3D。这是我的异步方法:
private void Receive(IAsyncResult ar)
{
try
{
IPEndPoint ipEndPoint = null;
byte[] data = udpClient.EndReceive(ar, ref ipEndPoint);
string receivedMessage = Encoding.UTF8.GetString(data);
JsonData json = JsonConvert.DeserializeObject<JsonData>(receivedMessage);
string prefix = json.header.Substring(0, 2);
Debug.Log("UDP World: " + receivedMessage);
if (prefix != "3x")
{
Debug.Log("Unknown packet: " + receivedMessage + "\n");
}
else
{
string header = json.header.Substring(2);
int conId = json.connectionId;
switch (header)
{
default:
Debug.Log("Unknown packet: " + receivedMessage + "\n");
break;
case "001":
Debug.Log("Data received: " + receivedMessage + "\n");
break;
case "002":
CharacterPosition position = new CharacterPosition();
position.x = float.Parse(json.data["position.x"].ToString());
position.y = float.Parse(json.data["position.y"].ToString());
position.z = float.Parse(json.data["position.z"].ToString());
Character.updateCharacterPosition(position, Convert.ToInt32(json.data["characterId"].ToString()), conId);
break;
case "003":
ClientWorldServer.character.updateCharacterRotation(json.data, conId);
break;
}
}
} catch (SocketException e)
{
Debug.Log("UDP Socket Exception: " + e);
}
udpClient.BeginReceive(Receive, null);
}
这是从Receive()
调用时无法正常工作的函数:
public static void updateCharacterPosition(CharacterPosition position, int characterId, int cnnId)
{
if (Character.SceneLoaded != true)
return;
Debug.Log("Position 2: X: " + position.x + " Y: " + position.y + " Z: " + position.z);
Debug.Log("GameObject FIND: " + GameObject.Find("CharactersOnline").name);
if (cnnId != ClientWorldServer.connectionId)
{
GameObject startPoint = GameObject.Find("CharactersOnline/" + characterId.ToString());
GameObject endPoint = new GameObject();
endPoint.transform.position = new Vector3(position.x, position.y, position.z);
GameObject.Find("CharactersOnline/" + characterId.ToString()).transform.position = Vector3.Lerp(startPoint.transform.position, endPoint.transform.position, Time.deltaTime);
//Updating Clients ram of the character's position
Character.characterDetails[int.Parse(characterId.ToString())].characterPosition.x = position.x;
Character.characterDetails[int.Parse(characterId.ToString())].characterPosition.y = position.y;
Character.characterDetails[int.Parse(characterId.ToString())].characterPosition.z = position.z;
//Destroy(endPoint);
}
}
我在Unity控制台中看到的全部是以下内容的输出:
Debug.Log("Position 2: X: " + position.x + " Y: " + position.y + " Z: " + position.z + " Character: " + characterId + " CnnID: " + cnnId);
使用上面显示的Debug.Log,我可以看到我具有所需的所有信息。 Debug.Log中的所有内容均已存在。 下一行:
Debug.Log("GameObject FIND: " + GameObject.Find("CharactersOnline").name);
似乎是一切刹车的地方。我从那条线都没有收到任何输出,也没有任何错误。看起来好像呆在那里,没有给出任何输出或错误。
从另一个非异步方法调用updateCharacterPosition
时,updateCharacterPosition
中的所有内容都按缩进方式工作。
任何想法为什么会发生这种奇怪的行为。如何解决该问题,以便可以从updateCharacterPosition
调用Receive
,这是异步功能?
答案 0 :(得分:1)
尝试一下: / *将其附加到场景中的任何对象上,以使其起作用* /
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MainThread : MonoBehaviour {
class CallInfo
{
public Function func;
public object parameter;
public CallInfo(Function Func, object Parameter)
{
func = Func;
parameter = Parameter;
}
public void Execute()
{
func(parameter);
}
}
public delegate void Function(object parameter);
public delegate void Func();
static List<CallInfo> calls = new List<CallInfo>();
static List<Func> functions = new List<Func>();
static Object callsLock = new Object();
static Object functionsLock = new Object();
void Start()
{
calls = new List<CallInfo>();
functions = new List<Func>();
StartCoroutine(Executer());
}
public static void Call(Function Func, object Parameter)
{
lock(callsLock)
{
calls.Add(new CallInfo(Func, Parameter));
}
}
public static void Call(Func func)
{
lock(functionsLock)
{
functions.Add(func);
}
}
IEnumerator Executer()
{
while(true)
{
yield return new WaitForSeconds(0.01f);
while(calls.Count > 0)
{
calls[0].Execute();
lock(callsLock)
{
calls.RemoveAt(0);
}
}
while(functions.Count > 0)
{
functions[0]();
lock(functionsLock)
{
functions.RemoveAt(0);
}
}
}
}
}
像这样打电话
MainThread.Call(YourFunction);
MainThread.Call(YourFunction, parameters);
我认为您的问题是您正在从另一个不允许的线程中调用Unity方法