2

相互に通信する必要がある 2 つの Unity プロジェクトがあるプロジェクトに取り組んでいます。.net Remoting Framework を使用してこれを解決しようとしています。そのために、両方の Unity プロジェクトが使用する dll を作成しました。dll は次のもので構成されます。

MyRemotableObject.cs

public class MyRemotableObject : MarshalByRefObject
{
    public MyRemotableObject()
    {

    }
    public void NotifyStatusChange(int status)
    {
        Cache.GetInstance().Status = 0;
    }
    public int GetCreditCount()
    {
        return Cache.GetInstance().CreditCount;
    }
}

キャッシュ.cs

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();
        }
    }
}

IObserver.cs

public interface IObserver
{
    void NotifyFinished(int status);
    int QueryCreditCount();
}

これで、リモーティング サーバーとして機能する Menu - Unity プロジェクトができました

MenuController.cs

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;
    }
}

このサーバーは、IObserver 関数の NotifyFinished と QueryCreditCount を実装しています (一時的にダミーの値を返します) クライアントから NotifyFinished 関数を呼び出すと、次のエラーが発生します。

get_animation は、メイン スレッドからのみ呼び出すことができます。コンストラクターとフィールド初期化子は、シーンのロード時にロード スレッドから実行されます。コンストラクターまたはフィールド初期化子でこの関数を使用しないでください。代わりに、初期化コードを Awake または Start 関数に移動してください。

誰かがこの問題を解決する方法を教えてもらえますか?

前もって感謝します、

ホフマニュエル

4

1 に答える 1

0

たくさん検索した後、解決策にたどり着きました: Using the Loom Unity Package from: Unity Gems のスレッドに関するエントリと、 Unity Answers のスレッドに関するエントリ で述べたような使用:

    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());
        }
    }
于 2013-04-24T10:51:17.407 に答える