C#/Unity-无法从异步方法调用Unity方法 [英] C#/Unity - Failing to call Unity method from Asynchronous method
问题描述
我正在使用Unity3D.这是我的异步方法:
I am using Unity3D. Here is my Asynchronous method:
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()
调用时无法正常工作的函数:
Here is the function which is not working corectly when called from 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控制台中看到的只是输出:
All I see in Unity's console is the output from:
Debug.Log("Position 2: X: " + position.x + " Y: " + position.y + " Z: " + position.z + " Character: " + characterId + " CnnID: " + cnnId);
使用上面显示的Debug.Log,可以看到我具有所需的所有信息. Debug.Log中的所有内容均已存在. 下一行:
With the Debug.Log shown above I can see that i have all the information needed. Everything in the Debug.Log is there. The next line:
Debug.Log("GameObject FIND: " + GameObject.Find("CharactersOnline").name);
似乎是一切刹车的地方.我从那条线都没有收到任何输出,也没有任何错误.看起来好像呆在那里,没有给出任何输出或错误.
seems to be the place where everything brakes. I do not receive any output from that line neither error whatsoever. It just looks like it stays there not giving any output or error.
从另一个非异步方法调用updateCharacterPosition
时,updateCharacterPosition
中的所有内容都按缩进方式工作.
When updateCharacterPosition
is called from another method which is not Asynchronous everything inside updateCharacterPosition
is working as indented.
任何想法为什么会发生这种奇怪的行为.我该如何解决,以便可以从Receive
调用updateCharacterPosition
,这是异步功能?
Any idea why this strange behavior is occurring. How can I fix that so i can call updateCharacterPosition
from Receive
which is Async function?
推荐答案
尝试一下: /*将其附加到场景中的任何对象上,以使其起作用*/
Try this: /* Attach this to any object in your scene, to make it work */
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方法
I think your problem is that you are calling Unity method from another thread which is not allowed
这篇关于C#/Unity-无法从异步方法调用Unity方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!