Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity.net远程处理服务器get_动画只能从主线程调用_C#_Thread Safety_Unity3d_Remoting - Fatal编程技术网

C# Unity.net远程处理服务器get_动画只能从主线程调用

C# Unity.net远程处理服务器get_动画只能从主线程调用,c#,thread-safety,unity3d,remoting,C#,Thread Safety,Unity3d,Remoting,我正在进行一个项目,其中我有两个Unity项目需要相互沟通。我试图通过使用.net远程处理框架来解决这个问题。 为此,我创建了一个dll,这两个Unity项目都将使用它。dll由以下部分组成: MyRemotableObject.cs Cache.cs IObserver.cs 现在我有了菜单-Unity项目,充当远程处理服务器 MenuController.cs public类MenuController:monobhavior,IObserver { 私有对象; 列出控制器; 私有MyRem

我正在进行一个项目,其中我有两个Unity项目需要相互沟通。我试图通过使用.net远程处理框架来解决这个问题。 为此,我创建了一个dll,这两个Unity项目都将使用它。dll由以下部分组成:

MyRemotableObject.cs

Cache.cs

IObserver.cs

现在我有了菜单-Unity项目,充当远程处理服务器

MenuController.cs

public类MenuController:monobhavior,IObserver
{
私有对象;
列出控制器;
私有MyRemotableObject remotableObject;
private System.ComponentModel.Container components=null;
无效唤醒()
{
lockObject=新对象();
尝试
{
remotableObject=新的MyRemotableObject();
//für fehler://http://www.mycsharp.de/wbb2/thread.php?postid=199935
//*************************************TCP*************************************//
//使用TCP协议
TCP通道=新的TCP通道(124);
ChannelServices.RegisterChannel(channel,false);
RegisterWellKnownServiceType(typeof(MyRemotableObject),“TargetShooterMenu”,WellKnownObjectMode.SingleCall);
//*************************************TCP*************************************//
RemotableObjects.Cache.Attach(此);
}
捕获(例外e)
{
Log(例如ToString());
}
控制器=新列表();
foreach(GameObject.FindGameObjectsWithTag(GlobalNames.Tags.controllerObject)中的GameObject controllerObject)
{
if(controllerObject.GetComponent())
Add(controllerObject.GetComponent());
}
}
委托无效PresentNameInputControllerDelegate(int状态);
私有void PresentNameInputController(int状态)
{
如果(状态==(int)LevelStatusCode.OK)
foreach(控制器中的控制器基控制器)
{
controller.Hide();
if(controller.GetType()==typeof(NameInputController))
controller.Show();
}
}
公共已完成(int状态)
{
调试日志(“通知”);
锁定(锁定对象)
{
PresentNameInputControllerDelegate d=PresentNameInputController;
d(地位);
}
}
public int QueryCreditCount()
{
Debug.Log(“查询”);
返回100;
}
}
此服务器实现IObserver函数NotifyFinished和QueryCreditCount(当前返回伪值) 从客户端调用NotifyFinished函数时,发生以下错误:

get_动画只能从主线程调用。 加载场景时,将从加载线程执行构造函数和字段初始值设定项。 不要在构造函数或字段初始值设定项中使用此函数,而是将初始化代码移到Awake或Start函数中

有人能告诉我怎么解决这个问题吗

提前感谢,


Hoffmanuel

经过大量搜索,我找到了解决方案:使用Loom Unity软件包,来自: 并使用它,如中所述:


此链接不再可用,因此我将其标记为副本,以帮助其他人解决您的问题。这只是一个小问题,但为什么我是比我晚几年提出的问题的副本?原因太多了。1.你链接的Gems插件包不再像我在第一条评论中说的那样可用。当人们找到这个答案时,它对他们没有用处。2.你的回答从来没有真正解释过这个问题,也没有提供解决问题的方法。你的答案基本上是“使用这个插件”。这基本上是一个链接唯一的答案。当链接站点消失后,问题和答案将不再有用。3.重复项的标记不是基于日期,而是基于帖子的详细程度或帮助程度。在考虑一个问题之前,我考虑所有这些。好的,谢谢你的反馈,我以后会考虑这个问题。
public class MyRemotableObject : MarshalByRefObject
{
    public MyRemotableObject()
    {

    }
    public void NotifyStatusChange(int status)
    {
        Cache.GetInstance().Status = 0;
    }
    public int GetCreditCount()
    {
        return Cache.GetInstance().CreditCount;
    }
}
public class Cache
{
    private static Cache myInstance;
    public static IObserver Observer;
    private Cache()
    {

    }
    public static void Attach(IObserver observer)
    {
        Observer = observer;
    }
    public static Cache GetInstance()
    {
        if(myInstance==null)
        {
            myInstance = new Cache();
        }
        return myInstance;
    }

    public int Status
    {
        set
        {
            Observer.NotifyFinished(value);
        }
    }
    public int CreditCount
    {
        get
        {
            return Observer.QueryCreditCount();
        }
    }
}
public interface IObserver
{
    void NotifyFinished(int status);
    int QueryCreditCount();
}
public class MenuController : MonoBehaviour, IObserver
{
    private object lockObject;
    List<ControllerBase> controllers;
    private MyRemotableObject remotableObject;
    private System.ComponentModel.Container components = null;

    void Awake()
    {
        lockObject = new object();
        try
        {
            remotableObject = new MyRemotableObject();

            //für fehler:  //http://www.mycsharp.de/wbb2/thread.php?postid=199935
            //************************************* TCP *************************************//
            // using TCP protocol
            TcpChannel channel = new TcpChannel(124);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyRemotableObject), "TargetShooterMenu", WellKnownObjectMode.SingleCall);
            //************************************* TCP *************************************//
            RemotableObjects.Cache.Attach(this);
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }

        controllers = new List<ControllerBase>();
        foreach (GameObject controllerObject in GameObject.FindGameObjectsWithTag(GlobalNames.Tags.CONTROLLEROBJECT))
        {
            if (controllerObject.GetComponent<ControllerBase>())
                controllers.Add(controllerObject.GetComponent<ControllerBase>());
        }
    }
    delegate void PresentNameInputControllerDelegate(int status);
    private void PresentNameInputController(int status)
    {
        if (status == (int)LevelStatusCode.OK)
            foreach (ControllerBase controller in controllers)
            {
                controller.Hide();
                if (controller.GetType() == typeof(NameInputController))
                    controller.Show();
            }
    }
    public void NotifyFinished(int status)
    {
        Debug.Log("Notify");
        lock (lockObject)
        {
            PresentNameInputControllerDelegate d = PresentNameInputController;

            d(status);
        }
    }
    public int QueryCreditCount()
    {
        Debug.Log("Query");
        return 100;
    }
}
    void Start()
    {
        var tmp = Loom.Current;
        ...
    }
    //Function called from other Thread
    public void NotifyFinished(int status)
    {
        Debug.Log("Notify");
        try
        {
            if (status == (int)LevelStatusCode.OK)
            {
                Loom.QueueOnMainThread(() =>
                {
                    PresentNameInputController();
                });
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }