I am working on Unity3d game that I wish to publish on Facebook.
Information about setup:
As you know, Facebook Canvas provide option to use Unity Integration. Description of this options is:
"Yes" to use the Facebook Unity SDK
But I want to have custom canvas page that is shown before unity player is loaded. So that's why I need to stop using Unity Integration of Facebook Canvas. So currently I have a server that serves my application. Everything works fine except the unity plugin.
First problem I faced is the lack of CanvasFacebook.dll
and AuthToken.unityhash
files. I solved this by downloading them from this link (dll) and this one (unityhash). And placed them in appropriate paths (rsrc/unity/lib/sdk_6.1/CanvasFacebook.dll
and rsrc/unity/key/sdk_6.1/AuthToken.unityhash
) on my server. So now FB.cs
loads this dll without problems.
But now I another problem. In FB.cs
there is a code:
var fb = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass)
.Invoke(null, new object[] { IfNotExist.AddNew }) as IFacebook;
This code works when I use Unity Integration in Facebook Canvas. But when I disable Unity Integration and run application inside of facebook - mentioned code executes and fails (without any errors or messages). How do I know that it fails? Well, it doesn't go further. Simple check - add Debug.Log("Got/Added CanvasFacebook component");
right after var fb = ... ;
and see that Log
method is not called. BTW, I have a log handler that calls something like Application.ExternalCall("console.log", message)
, but with some pretty stuff.
Ok, so I tried to check, why this code is not working with custom canvas. Why I think that dll is loaded and should work? Because right after
var assembly = Security.LoadAndVerifyAssembly(www.bytes, authTokenWww.text); ... var facebookClass = assembly.GetType(facebookNamespace + className);
facebookClass
is not null and equals to CanvasFacebook
. More over, I found that
var methodInfo = typeof(FBComponentFactory)
.GetMethod("GetComponent")
.MakeGenericMethod(facebookClass);
Also works. It's just the problem with invoking this method. When I try to
var fb = methodInfo.Invoke(null, new object[] { IfNotExist.ReturnNull }) as IFacebook;
Call works, but fb
is null
. So I checked FBComponentFactory
class using ILSpy
on IFacebook.dll
from sdk. And here is class definition:
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>();
}
}
}
So now I think that the problem is with adding component. But it doesn't throw any errors (well, I couldn't catch any using try catch
). So I tried to AddComponent from FB.cs
explicitly (I know that this is ugly hack, but I am just trying to understand the root of problem):
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;
I use log errors, because they will call console.error
and it's a bit easier to see in browser logs.
So when I build game with this changes and run inside of facebook canvas, I see next output:
[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
But the code Debug.LogError("got component of type: " + component.GetType());
is not executed. No errors, no exceptions. Executer (or how does it called) simply moves out from this method and goes on. I can play my game, but facebook plugin is not working.
And again. Previous code doesn't throw any exceptions (at least, I couldn't catch them using try catch
).
Also, when I check Player.log
file, I see:
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
So it shows that everything is fine. But actually, plugin is not loaded. When I try to use FB.Login
I see:
180.49 Facebook: tried to login but we're not init'd yet.
Question(s)
Sorry for such long post. But here are my questions:
CanvasFacebook
dll is corrupted?AddComponent
. Have anyone experienced something similar?And main question:
Is it possible to use Facebook Unity SDK and custom canvas? I know that I can just create my own bridge between JS SDK and Unity SDK, but I don't like the idea, when I know that someone already created it and the only problem - creating CanvasFacebook
component.
Thanks in advance.
The question is rather old. But since version 7.0.0
of facebook plugin described flow is possible.
For more information checkout official documentation.