WP8:Unity3D之间的值传递

在前面的讨论中,我们介绍了如何在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发送消息的方法,包括BroadcastMessageSendMessage以及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(), GUILayout.Height()))
{
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之间进行值传递

上一篇:C++ 系列:多线程资源收集


下一篇:用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板