c# - C#/Unity - 无法从异步方法调用 Unity 方法
问题描述
我正在使用 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
Async 函数?
解决方案
试试这个:/* 将它附加到场景中的任何对象上,以使其工作 */
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 方法
推荐阅读
- node.js - 如何在 discord.js 上发出“说”命令?
- angular - 构建电容器时没有导出成员“需要”
- reactjs - 阻止所有组件渲染
- python - Word 内容控制 - 字段:从字段中的数据自动生成文档上的 QR 码
- c - 如何从 C 中的标准输入读取多行字符串?
- javascript - API调用反应,访问数据的问题
- r - 循环函数没有在 R 中返回正确的结果
- git - 无法从 Android Studio 中的 Github 拉取
- angular - 来自 API 错误的 Angular GET:找不到类型为“object”的不同支持对象“[object Object]”
- c++ - 确定 C++ 标准算法函数的返回类型,如 count_if