C#/Unity - 无法从异步方法调用 Unity 方法 [英] C#/Unity - Failing to call Unity method from Asynchronous method

查看:74
本文介绍了C#/Unity - 无法从异步方法调用 Unity 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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 + "
");
        }
        else
        {
            string header = json.header.Substring(2);
            int conId = json.connectionId;
            switch (header)
            {
                default:
                    Debug.Log("Unknown packet: " + receivedMessage + "
");
                    break;
                case "001":
                    Debug.Log("Data received: " + receivedMessage + "
");
                    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆