天天看點

WP8:Unity3D之間的值傳遞

在實際的開發需求中,除了通過回調來調用第三方庫的方法,還能通過消息機制通知Unity3D一些值的變化。每個Unity3D的腳本類都繼承了Component類,Component類實作了幾個向game object發送消息的方法

在前面的讨論中,我們介紹了如何在Unity3D for WP8中使用高于.Net 3.5的第三方庫,傳送門:http://www.cnblogs.com/zhxilin/p/3311240.html

在Unity3D和WP8的互動當中,如果要使用第三方插件(dll),通常的方式都會想到直接在Unity3D的Assets中添加一堆Plugins。但是這種做法的局限性非常明顯,就是隻能添加基于.Net3.5的dll。如果第三方插件是基于.Net 3.5編寫的完全沒有問題,但令人頭疼的是大部分第三方插件都不是基于.Net3.5來編寫的,至少使用了.Net 4或.Net 4.5,如果再以Plugins添加到U3D的Assets中是根本編譯不通過的。是以才有了我們前面那篇文章的讨論,借助UnityPlayer中UnityApp類的SetLoadedCallback來回調操作。

在實際的開發需求中,除了通過回調來調用第三方庫的方法,還能通過消息機制通知Unity3D一些值的變化。每個Unity3D的腳本類都繼承了Component類,Component類實作了幾個向game object發送消息的方法,包括BroadcastMessage、SendMessage以及SendMessageUpwards

在Unity的API文檔定義如下

方法 描述
BroadcastMessage Calls the method named methodName on every MonoBehaviour in this game object or any of its children.
SendMessage Calls the method named methodName on every MonoBehaviour in this game object.
SendMessageUpwards Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor of the behaviour.

 舉個例子,假設在一個MonoBehaviour中,需要使用到OpenXLive提供的PlayerID,前面提到,OpenXLive是基于.Net 4.5的第三方遊戲社交平台,我們無法直接将OpenXLive.dll作為Plugins的形式導入Unity工程,是以我們沒法直接在MonoBehaviour裡取到PlayerID。但是我們可以利用消息機制,很好地将需要的值從WP8中傳遞給Unity。

假設我們建立了一個C#腳本叫MyScript.cs,定義一個UsePlayerID方法

using System.Reflection.Emit;
using UnityEngine;
using System.Collections;
using System;

public class MyScript : MonoBehaviour {

    public event EventHandler GameCenterButtonPressed;
    public event EventHandler SubmitScoreButtonPressed;

    void OnGUI()
    {
        if (GUILayout.Button("Game Center", GUILayout.Width(300), GUILayout.Height(40)))
        {
            if (GameCenterButtonPressed != null)
            {
                GameCenterButtonPressed(this, EventArgs.Empty);
            }
        }
    }

    void UsePlayerID(string Id)
    {
        // Use the player id here.
    }
}      

那麼在MonoBehaviour中就可以随處調用GetPlayerID方法拿到玩家的ID,然而它的值從何而來?

将Unity工程導出為WP8工程并打開,在MainPage.xaml.cs中,可以看到DrawingSurfaceBackground_Loaded方法中UnityApp.SetLoadedCallback(() => { Dispatcher.BeginInvoke(Unity_Loaded); });

在Unity加載完成後就通知了這裡的Unity_Loaded方法,完成加載後就可以取出Unity中的腳本對象:

private  MyScript script;

private void Unity_Loaded()
{
  script = (MyScript)UnityEngine.Object.FindObjectOfType(typeof(MyScript));
  script.GameCenterButtonPressed += script_GameCenterButtonPressed;
}

private void script_GameCenterButtonPressed(object sender, EventArgs e)
{
  this.Dispatcher.BeginInvoke(delegate
  {
    OpenXLive.Features.GameSession session = OpenXLive.XLiveGameManager.CreateSession("xxxxxxxxxxxxxxxxxxxxxx");
    session.CreateSessionCompleted += session_CreateSessionCompleted;

    XLiveUIManager.Initialize(Application.Current, session);
    session.Open();
  });
}

void session_CreateSessionCompleted(object sender, OpenXLive.AsyncEventArgs e)
{
  this.Dispatcher.BeginInvoke(delegate
  {
    if (e.Result.ReturnValue)
    {
      script.SendMessage("UsePlayerID", XLiveGameManager.CurrentSession.AnonymousID);
    }
  });
}      

調用SendMessage方法,将PlayerID作為UsePlayerID所需的參數傳遞過去,通知MyScript對象執行UsePlayerID方法。

以上,介紹了在WP8和Unity3D之間進行值傳遞