在没有 Unity Integration(或其他桥接选项)的情况下加载 CanvasFacebook.dll
Load CanvasFacebook.dll without Unity Integration (or other bridge options)
我正在开发希望在 Facebook 上发布的 Unity3d 游戏。
关于设置的信息:
- 统一 4.6.1
- Unity Facebook SDK v6.1.0
- 我正在使用 OS X 进行构建。在 Safari 中测试游戏。
如您所知,Facebook Canvas 提供使用 Unity Integration 的选项。此选项的说明是:
"Yes" to use the Facebook Unity SDK
但我想要在加载统一播放器之前显示自定义 canvas 页面。所以这就是为什么我需要停止使用 Facebook Canvas 的 Unity Integration。所以目前我有一台服务器为我的应用程序提供服务。除了 unity 插件,一切正常。
我面临的第一个问题是缺少 CanvasFacebook.dll
和 AuthToken.unityhash
文件。我通过从 this link (dll) and this one (unityhash) 下载它们解决了这个问题。并将它们放在我服务器上的适当路径(rsrc/unity/lib/sdk_6.1/CanvasFacebook.dll
和 rsrc/unity/key/sdk_6.1/AuthToken.unityhash
)中。所以现在 FB.cs
加载这个 dll 没有问题。
但是现在我又遇到了一个问题。在FB.cs
中有一个代码:
var fb = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass)
.Invoke(null, new object[] { IfNotExist.AddNew }) as IFacebook;
当我在 Facebook Canvas 中使用 Unity Integration 时,此代码有效。但是当我在 facebook 中禁用 Unity Integration 和 运行 应用程序时 - 提到的代码执行并失败(没有任何错误或消息)。我怎么知道它失败了?好吧,它不会更进一步。简单检查 - 在 var fb = ... ;
之后添加 Debug.Log("Got/Added CanvasFacebook component");
并查看未调用 Log
方法。顺便说一句,我有一个日志处理程序调用类似 Application.ExternalCall("console.log", message)
的东西,但有一些漂亮的东西。
好的,所以我尝试检查为什么此代码不适用于自定义 canvas。为什么我认为 dll 已加载并且应该可以工作?因为紧接着
var assembly = Security.LoadAndVerifyAssembly(www.bytes, authTokenWww.text);
...
var facebookClass = assembly.GetType(facebookNamespace + className);
facebookClass
不为空且等于 CanvasFacebook
。此外,我发现
var methodInfo = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass);
也有效。这只是调用此方法的问题。当我尝试
var fb = methodInfo.Invoke(null, new object[] { IfNotExist.ReturnNull }) as IFacebook;
呼叫有效,但 fb
是 null
。所以我在 sdk 的 IFacebook.dll
上使用 ILSpy
检查了 FBComponentFactory
class。这是 class 定义:
using System;
using UnityEngine;
namespace Facebook
{
public class FBComponentFactory
{
public const string gameObjectName = "UnityFacebookSDKPlugin";
private static GameObject facebookGameObject;
private static GameObject FacebookGameObject
{
get
{
if (FBComponentFactory.facebookGameObject == null)
{
FBComponentFactory.facebookGameObject = new GameObject("UnityFacebookSDKPlugin");
}
return FBComponentFactory.facebookGameObject;
}
}
public static T GetComponent<T>(IfNotExist ifNotExist = IfNotExist.AddNew) where T : MonoBehaviour
{
GameObject gameObject = FBComponentFactory.FacebookGameObject;
T t = gameObject.GetComponent<T>();
if (t == null && ifNotExist == IfNotExist.AddNew)
{
t = gameObject.AddComponent<T>();
}
return t;
}
public static T AddComponent<T>() where T : MonoBehaviour
{
return FBComponentFactory.FacebookGameObject.AddComponent<T>();
}
}
}
所以现在我认为问题在于添加组件。但它不会抛出任何错误(好吧,我无法使用 try catch
捕捉到任何错误)。所以我尝试从 FB.cs
明确地添加组件(我知道这是丑陋的 hack,但我只是想了解问题的根源):
var type = typeof(FBComponentFactory);
Debug.LogError("I got type: " + type);
var fieldInfo = type.GetField("facebookGameObject", BindingFlags.NonPublic | BindingFlags.Static);
Debug.LogError("I got fieldInfo: " + fieldInfo);
var go = fieldInfo.GetValue(null) as GameObject;
if (go == null) {
Debug.LogError("go is null, so creating new one");
fieldInfo.SetValue(null, new GameObject("UnityFacebookSDKPlugin"));
go = fieldInfo.GetValue(null) as GameObject;
}
Debug.LogError("I got go with name: " + (go == null ? "null" : go.name));
var component = go.AddComponent(facebookClass);
Debug.LogError("got component of type: " + component.GetType());
var fb = component is IFacebook;
我使用日志错误,因为它们会调用 console.error
并且在浏览器日志中更容易看到。
因此,当我使用此更改和 运行 在 facebook canvas 中构建游戏时,我看到下一个输出:
[Error] 7.24 I got type: Facebook.FBComponentFactory
[Error] 7.24 I got fieldInfo: UnityEngine.GameObject facebookGameObject
[Error] 7.24 I got go with name: UnityFacebookSDKPlugin
但是代码Debug.LogError("got component of type: " + component.GetType());
没有执行。没有错误,没有异常。 Executer(或者它是如何调用的)简单地从这个方法中移出并继续。我可以玩我的游戏,但 facebook 插件不工作。
又一次。以前的代码没有抛出任何异常(至少,我无法使用 try catch
捕获它们)。
此外,当我检查 Player.log
文件时,我看到:
7.24 I got type: Facebook.FBComponentFactory
7.24 I got fieldInfo: UnityEngine.GameObject facebookGameObject
7.24 I got go: UnityFacebookSDKPlugin
7.24 got component of type: Facebook.CanvasFacebook
所以说明一切正常。但实际上,插件没有加载。当我尝试使用 FB.Login
时,我看到:
180.49 Facebook: tried to login but we're not init'd yet.
问题
抱歉这么久post。但这是我的问题:
- 有人知道这里到底发生了什么吗?
- 是否有可能
CanvasFacebook
dll 已损坏?
- 我找不到有关
AddComponent
此类行为的任何信息。有人经历过类似的事情吗?
主要问题:
是否可以使用 Facebook Unity SDK 和 自定义 canvas?我知道我可以在 JS SDK 和 Unity SDK 之间创建自己的桥梁,但我不喜欢这个想法,因为我知道有人已经创建了它,唯一的问题是创建 CanvasFacebook
组件。
提前致谢。
问题有点老了。但由于 facebook 插件版本 7.0.0
描述的流程是可能的。
有关更多信息,请查看 official documentation。
我正在开发希望在 Facebook 上发布的 Unity3d 游戏。
关于设置的信息:
- 统一 4.6.1
- Unity Facebook SDK v6.1.0
- 我正在使用 OS X 进行构建。在 Safari 中测试游戏。
如您所知,Facebook Canvas 提供使用 Unity Integration 的选项。此选项的说明是:
"Yes" to use the Facebook Unity SDK
但我想要在加载统一播放器之前显示自定义 canvas 页面。所以这就是为什么我需要停止使用 Facebook Canvas 的 Unity Integration。所以目前我有一台服务器为我的应用程序提供服务。除了 unity 插件,一切正常。
我面临的第一个问题是缺少 CanvasFacebook.dll
和 AuthToken.unityhash
文件。我通过从 this link (dll) and this one (unityhash) 下载它们解决了这个问题。并将它们放在我服务器上的适当路径(rsrc/unity/lib/sdk_6.1/CanvasFacebook.dll
和 rsrc/unity/key/sdk_6.1/AuthToken.unityhash
)中。所以现在 FB.cs
加载这个 dll 没有问题。
但是现在我又遇到了一个问题。在FB.cs
中有一个代码:
var fb = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass)
.Invoke(null, new object[] { IfNotExist.AddNew }) as IFacebook;
当我在 Facebook Canvas 中使用 Unity Integration 时,此代码有效。但是当我在 facebook 中禁用 Unity Integration 和 运行 应用程序时 - 提到的代码执行并失败(没有任何错误或消息)。我怎么知道它失败了?好吧,它不会更进一步。简单检查 - 在 var fb = ... ;
之后添加 Debug.Log("Got/Added CanvasFacebook component");
并查看未调用 Log
方法。顺便说一句,我有一个日志处理程序调用类似 Application.ExternalCall("console.log", message)
的东西,但有一些漂亮的东西。
好的,所以我尝试检查为什么此代码不适用于自定义 canvas。为什么我认为 dll 已加载并且应该可以工作?因为紧接着
var assembly = Security.LoadAndVerifyAssembly(www.bytes, authTokenWww.text); ... var facebookClass = assembly.GetType(facebookNamespace + className);
facebookClass
不为空且等于 CanvasFacebook
。此外,我发现
var methodInfo = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass);
也有效。这只是调用此方法的问题。当我尝试
var fb = methodInfo.Invoke(null, new object[] { IfNotExist.ReturnNull }) as IFacebook;
呼叫有效,但 fb
是 null
。所以我在 sdk 的 IFacebook.dll
上使用 ILSpy
检查了 FBComponentFactory
class。这是 class 定义:
using System;
using UnityEngine;
namespace Facebook
{
public class FBComponentFactory
{
public const string gameObjectName = "UnityFacebookSDKPlugin";
private static GameObject facebookGameObject;
private static GameObject FacebookGameObject
{
get
{
if (FBComponentFactory.facebookGameObject == null)
{
FBComponentFactory.facebookGameObject = new GameObject("UnityFacebookSDKPlugin");
}
return FBComponentFactory.facebookGameObject;
}
}
public static T GetComponent<T>(IfNotExist ifNotExist = IfNotExist.AddNew) where T : MonoBehaviour
{
GameObject gameObject = FBComponentFactory.FacebookGameObject;
T t = gameObject.GetComponent<T>();
if (t == null && ifNotExist == IfNotExist.AddNew)
{
t = gameObject.AddComponent<T>();
}
return t;
}
public static T AddComponent<T>() where T : MonoBehaviour
{
return FBComponentFactory.FacebookGameObject.AddComponent<T>();
}
}
}
所以现在我认为问题在于添加组件。但它不会抛出任何错误(好吧,我无法使用 try catch
捕捉到任何错误)。所以我尝试从 FB.cs
明确地添加组件(我知道这是丑陋的 hack,但我只是想了解问题的根源):
var type = typeof(FBComponentFactory);
Debug.LogError("I got type: " + type);
var fieldInfo = type.GetField("facebookGameObject", BindingFlags.NonPublic | BindingFlags.Static);
Debug.LogError("I got fieldInfo: " + fieldInfo);
var go = fieldInfo.GetValue(null) as GameObject;
if (go == null) {
Debug.LogError("go is null, so creating new one");
fieldInfo.SetValue(null, new GameObject("UnityFacebookSDKPlugin"));
go = fieldInfo.GetValue(null) as GameObject;
}
Debug.LogError("I got go with name: " + (go == null ? "null" : go.name));
var component = go.AddComponent(facebookClass);
Debug.LogError("got component of type: " + component.GetType());
var fb = component is IFacebook;
我使用日志错误,因为它们会调用 console.error
并且在浏览器日志中更容易看到。
因此,当我使用此更改和 运行 在 facebook canvas 中构建游戏时,我看到下一个输出:
[Error] 7.24 I got type: Facebook.FBComponentFactory
[Error] 7.24 I got fieldInfo: UnityEngine.GameObject facebookGameObject
[Error] 7.24 I got go with name: UnityFacebookSDKPlugin
但是代码Debug.LogError("got component of type: " + component.GetType());
没有执行。没有错误,没有异常。 Executer(或者它是如何调用的)简单地从这个方法中移出并继续。我可以玩我的游戏,但 facebook 插件不工作。
又一次。以前的代码没有抛出任何异常(至少,我无法使用 try catch
捕获它们)。
此外,当我检查 Player.log
文件时,我看到:
7.24 I got type: Facebook.FBComponentFactory
7.24 I got fieldInfo: UnityEngine.GameObject facebookGameObject
7.24 I got go: UnityFacebookSDKPlugin
7.24 got component of type: Facebook.CanvasFacebook
所以说明一切正常。但实际上,插件没有加载。当我尝试使用 FB.Login
时,我看到:
180.49 Facebook: tried to login but we're not init'd yet.
问题
抱歉这么久post。但这是我的问题:
- 有人知道这里到底发生了什么吗?
- 是否有可能
CanvasFacebook
dll 已损坏? - 我找不到有关
AddComponent
此类行为的任何信息。有人经历过类似的事情吗?
主要问题:
是否可以使用 Facebook Unity SDK 和 自定义 canvas?我知道我可以在 JS SDK 和 Unity SDK 之间创建自己的桥梁,但我不喜欢这个想法,因为我知道有人已经创建了它,唯一的问题是创建 CanvasFacebook
组件。
提前致谢。
问题有点老了。但由于 facebook 插件版本 7.0.0
描述的流程是可能的。
有关更多信息,请查看 official documentation。