unity3d与wp8之间的值传递
在开发过程中,我们常常会遇到需要实现 Unity3D 与 WP8 之间值传递的需求,下面将详细介绍其具体实现过程。
第三方插件使用的局限性
在 Unity3D 和 WP8 的交互中,若要使用第三方插件(dll),常见做法是直接在 Unity3D 的 Assets 中添加一堆 Plugins。然而,这种方式存在明显局限性,它仅支持添加基于 .Net3.5 的 dll。如果第三方插件是基于 .Net 3.5 编写的,使用这种方法不会有问题。但实际情况是,大部分第三方插件至少使用了 .Net 4 或 .Net 4.5,若将这类插件以 Plugins 的形式添加到 U3D 的 Assets 中,根本无法通过编译。因此,我们可以借助 UnityPlayer 中 UnityApp 类的 SetLoadedCallback 进行回调操作,具体可参考我们之前的文章。
消息机制在值传递中的应用
在实际开发中,除了通过回调来调用第三方库的方法,还可以利用消息机制通知 Unity3D 值的变化。每个 Unity3D 的脚本类都继承自 Component 类,而 Component 类实现了几个向游戏对象发送消息的方法,包括 BroadcastMessage、SendMessage 以及 SendMessageUpwards。这些方法在 Unity 的 API 文档中有详细定义。
下面通过一个具体例子来展示如何利用消息机制将 WP8 中的值传递给 Unity。假设在一个 MonoBehaviour 中需要使用 OpenXLive 提供的 PlayerID,OpenXLive 是基于 .Net 4.5 的第三方游戏社交平台,无法直接将 OpenXLive.dll 作为 Plugins 导入 Unity 工程,也就无法直接在 MonoBehaviour 里获取 PlayerID。但我们可以利用消息机制实现值的传递。
编写 C# 脚本
首先,创建一个名为 MyScript.cs 的 C# 脚本,并定义一个 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.
}
}
在这个脚本中,我们定义了两个事件 GameCenterButtonPressed 和 SubmitScoreButtonPressed,并在 OnGUI 方法中处理按钮点击事件。同时,定义了 UsePlayerID 方法用于处理玩家 ID。
在 WP8 工程中获取脚本对象并传递值
将 Unity 工程导出为 WP8 工程并打开,在 MainPage.xaml.cs 中,可以看到 DrawingSurfaceBackground_Loaded 方法中有如下代码:
UnityApp.SetLoadedCallback(() => { Dispatcher.BeginInvoke(Unity_Loaded); });
这行代码的作用是在 Unity 加载完成后通知 Unity_Loaded 方法。在 Unity_Loaded 方法中,我们可以取出 Unity 中的脚本对象:
private MyScript script;
private void Unity_Loaded() {
script = (MyScript)UnityEngine.Object.FindObjectOfType(typeof(MyScript));
script.GameCenterButtonPressed += script_GameCenterButtonPressed;
}
在 script_GameCenterButtonPressed 方法中,我们创建了 OpenXLive 的游戏会话,并在会话创建完成后,将 PlayerID 传递给 MyScript 对象:
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);
}
});
}
在 session_CreateSessionCompleted 方法中,我们调用 SendMessage 方法,将 PlayerID 作为 UsePlayerID 所需的参数传递过去,从而通知 MyScript 对象执行 UsePlayerID 方法。
通过以上步骤,我们就实现了 Unity3D 与 WP8 之间的值传递。