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

查看:156
本文介绍了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 + "\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屋!

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