原地址:http://www.cnblogs.com/zhxilin/p/3799210.html
在前面的讨论中,我们介绍了如何在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之间进行值传递