Я работаю над игрой Unity3d, которую хочу опубликовать на Facebook.
Информация о настройке:
- Единство 4.6.1
- Unity Facebook SDK v6.1.0
- Я использую OS X для сборки. Тестирование игры в Safari.
Как вы знаете, Facebook Canvas предоставляет возможность использовать интеграцию с Unity. Описание этих опций:
«Да», чтобы использовать Facebook Unity SDK
Но я хочу, чтобы настраиваемая страница холста отображалась до загрузки проигрывателя Unity. Вот почему мне нужно прекратить использовать интеграцию Unity с Facebook Canvas. Итак, в настоящее время у меня есть сервер, который обслуживает мое приложение. Все работает нормально, кроме плагина единства.
Первая проблема, с которой я столкнулся, это отсутствие файлов CanvasFacebook.dll
и AuthToken.unityhash
. Я решил эту проблему, загрузив их из по этой ссылке (dll) и это один (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;
Этот код работает, когда я использую Unity Integration в Facebook Canvas. Но когда я отключаю интеграцию Unity и запускаю приложение внутри facebook, указанный код выполняется и терпит неудачу (без каких-либо ошибок или сообщений). Как я узнаю, что это не удается? Ну дальше не идет. Простая проверка — добавляем Debug.Log("Got/Added CanvasFacebook component");
сразу после var fb = ... ;
и видим, что метод Log
не вызывается. Кстати, у меня есть обработчик журнала, который вызывает что-то вроде Application.ExternalCall("console.log", message)
, но с некоторыми красивыми вещами.
Итак, я попытался проверить, почему этот код не работает с пользовательским холстом. Почему я думаю, что dll загружается и должна работать? Потому что сразу после
сборка var = Security.LoadAndVerifyAssembly(www.bytes, authTokenWww.text); ... var facebookClass = Assembly.GetType(facebookNamespace + className);
facebookClass
не равно null и равно CanvasFacebook
. Более того, я обнаружил, что
var methodInfo = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass);
Также работает. Это просто проблема с вызовом этого метода. Когда я пытаюсь
var fb = methodInfo.Invoke(null, new object[] { IfNotExist.ReturnNull }) as IFacebook;
Вызов работает, но fb
это null
. Итак, я проверил класс FBComponentFactory
, используя ILSpy
на IFacebook.dll
из sdk. И вот определение класса:
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
(я знаю, что это уродливый хак, но я просто пытаюсь понять корень проблемы):
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, я вижу следующий вывод:
[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());
не выполняется. Никаких ошибок, никаких исключений. Исполнитель (или как он там называется) просто выходит из этого метода и идет дальше. Я могу играть в свою игру, но плагин 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.
Вопрос(ы)
Извините за такой длинный пост. Но вот мои вопросы:
- Кто-нибудь знает, что, черт возьми, здесь происходит?
- Возможно ли, что
CanvasFacebook
dll повреждена? - Я не смог найти никакой информации о таком поведении
AddComponent
. Кто-нибудь испытал что-то подобное?
И главный вопрос:
Можно ли использовать Facebook Unity SDK и собственный холст? Я знаю, что могу просто создать свой мост между JS SDK и Unity SDK, но мне не нравится идея, когда я знаю, что кто-то уже создал его и единственная проблема — создать CanvasFacebook
компонент.
Заранее спасибо.