在實際的開發需求中,除了通過回調來調用第三方庫的方法,還能通過消息機制通知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之間進行值傳遞