1. 程式人生 > >Unity 接入Facebook。登入、分享、邀請、好友列表等功能。

Unity 接入Facebook。登入、分享、邀請、好友列表等功能。

版本環境:Unity版本 5.3.4f1 Facebook版本 7.9.4

Facebook 提供了Unity SDK, 這比原生的方式接要方便很多。
1、在開發者後臺建立應用。
後臺地址:https://developers.facebook.com/apps/

2、下載Unity版本的SDK, 匯入Unity。
下載地址:https://developers.facebook.com/docs/unity/

3、配置方法如下圖。
facebook配置
可以從選單欄開啟EditSetting,也可以在Project檢視中直接找到FacebookSettings進行配置。
在Inspector中可以看到詳細的需要配置資訊。

第一部分,應用的基本資訊,可以在facebook後臺中找到,具體位置可以滑鼠移動到 “?”處檢視。
基本資訊
第二部分,FB.Init,使用預設設定即可,當然也可根據自己的實際需要配置。
FB.Init
第三部分,安卓/iOS的配置,因為沒有釋出IOS包,並沒有做IOS的處理。這裡只說安卓的。
安卓/iOS的配置
需要注意的有三點:
1),並不是要在這裡配置什麼,而是要把這裡的資訊配置到Facebook後臺的中(設定-基本設定-下方)。
2),這裡顯示的資訊並不正確,需要配置真實值。那真實值在哪裡?
package Name : 包名,你應用打包使用的包名
Class Name:啟動類名,你遊戲的啟動Acitivity。可以在AndroidManifest.xml中檢視。
Facebook將根據你配置的包名和啟動類名,在你好友點選邀請連結時啟動你的遊戲。
Key Hash : 邀請功能必須配置的引數。
可以google或baidu一下,有很多獲取方式,甚至有檢視Facebook Key Hash的工具存在。
最方便的方法是先填這裡不正確的,等報錯的時,填報錯中顯示的Key Hash。這個下邊再說。
3),配置完後記得執行 GenertateAndroidManifest.
生成之後把其中 需要的許可權、Acitivity,meta-data等配置Copy到你的遊戲AndroidManifest.xml中。

第四部分,App Links Settings, 邀請功能的第一個引數,可不填。這個在之後說邀請功能的時候再說。


4、接下來就是寫程式碼和做具體的功能了。
文件地址:https://developers.facebook.com/docs/unity/reference/current
遊戲中,用到的比較常見的功能有,
登入、分享、獲取自己的資訊、獲取好友列表(好友資訊列表)、邀請、分數排行榜等。
還提供了應用內打點統計等其他功能。

一、初始化
FB.Init()
初始化會返回 IsInitialized 的標誌。

二、登入
出於安全性考慮,Facebook的功能都必須在一定的許可權下進行, 所以也可以說登入就是一種授權行為。
它提供了兩種方式的登入, LogInWithReadPermissions 和 LogInWithPublishPermissions。
你可以根據自己需要的接入的功能選擇登入方式,並傳入許可權引數。

注意: 不能在LogInWithReadPermissions 中傳入Publish許可權,也不能在LogInWithPublishPermissions中傳入
Read許可權。
否則會報錯: Cannot pass a publish or manage
permission (xxx) to a request for ead authorization 或 Cannot pass a read permission (xxx) to a request for publish authorization

許可權參考: https://developers.facebook.com/docs/facebook-login/permissions

登入會返回IsLoggedIn的標誌 AccessToken,
AccessToken中包含UserId、TokenString、請求的許可權列表等資訊。

個人理解:需要登入才能做的功能(比如邀請、取好友列表)在執行前 會將AccessToken中的資訊傳入Facebook伺服器做驗證,驗證成功才能進行下一步操作。

三、分享

分享比較簡單,呼叫FB.ShareLink 傳入 跳轉連結、標題、內容、圖片連結 即可。

public static void ShareLink(Uri contentURL = null, string contentTitle = “”, string contentDescription = “”, Uri photoURL = null, FacebookDelegate
callback = null);

分享可以在沒有登入的時候呼叫,會自己調起登入授權。

四、獲取自己的資訊、好友資訊列表。
重點!!! Facebook 通過 Graph API(圖譜API) 來獲取使用者資料,或釋出內容(如分數)。
你必須先了解Graph API是什麼!
文件地址:https://developers.facebook.com/docs/graph-api

兩個過載的方法:
public static void API(string query, HttpMethod method, FacebookDelegate callback = null, IDictionary<string, string> formData = null);

public static void API(string query, HttpMethod method, FacebookDelegate callback, WWWForm formData);

其中,
第一個引數必須滿足FQL(facebook Query Language)的語法。可以傳入具體的查詢引數,查詢自己需要的資訊
第二個引數是 選擇獲取Get還是釋出Post。
第三個引數是 結果回撥。
第四個引數是 引數二選擇Post時附帶的釋出資訊。

1),什麼是FQL?
文件地址:https://developers.facebook.com/docs/technical-guides/fql/

2),資料的結構是怎樣的?
參考:https://developers.facebook.com/docs/graph-api/reference/user/

3),怎麼樣快速測一下我傳的query引數對不對?
Graph API探索工具:https://developers.facebook.com/tools/explorer

4),如何處理返回結果?
IGraphResult 中的 ResultList 是返回的結果,
但推薦直接使用其父類IResult 中的RawResult。
RawResult是一個Json字串,可以方便的在各種語言下解析,因為我們更多的用lua寫業務邏輯。
Facebook官方也提供了在C#中解析的工具:
文件參考:https://developers.facebook.com/docs/unity/reference/current/Json

注意:
1),“me/friends” 查詢到的結果是 已經登入過該遊戲/應用的facebook好友列表。
2),“me/friends” 需要在登入時加入 “user_friends” 許可權。

五、邀請
邀請和分享看起來差不多,但實際差別挺大的。

public static void AppInvite(Uri appLinkUrl, Uri previewImageUrl = null, FacebookDelegate
callback = null);

其中,
第一個引數 是一個可以通過Facebook定製的 DeepLink。
在好友點選你的邀請資訊時,Facebook通過該深連結根據不同的平臺或不同情形做不同的操作,
比如在未安裝遊戲時點選會開啟遊戲下載地址,安裝遊戲時會直接啟動遊戲。
介紹:https://developers.facebook.com/products/app-links
建立地址:https://developers.facebook.com/quickstarts/?platform=app-links-host

第二個引數 是一個可為空的引數,但建議傳入,否則不能在邀請傳送時預覽。

第三個引數 是結果回撥

注意:邀請功能需要在後臺配置正確的Key Hash,否則會報錯:

error: Invalid key hash. The key hash(此處顯示了正確的、需要配置的Key Hash)does
not match any stored key hashes. Configure your app key hashes at https://developers.facebook.com/apps/(遊戲的appid)/
將提示的Key hash 配到後臺即可。

奇怪的是,
public static void GetAppLink(FacebookDelegate callback);
Facebook貌似提供了該API來獲取AppLink,但實際上我在配置的第四部分,App Links Settings 中填了,也無法獲取到。
返回的結果,result.Ref、result.TargetUrl、result.Url均為 空字串 “”。
result.RawResult 為: {“did_complete”:true,“callback_id”:“3”}
如果有人遇到並解決了這個問題,請留言告訴我,非常感謝。

下面貼一下完整的程式碼:

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

using Facebook.Unity;
using Facebook.MiniJSON;

[SLua.CustomLuaClass]
public class MyFB
{
    public delegate void OnFBLoginSucced(Facebook.Unity.AccessToken token);
    public delegate void OnFBLoginFaild(bool isCancel, string errorInfo);
    public delegate void OnFBShareLinkSucced(string postId);
    public delegate void OnFBShareLinkFaild(bool isCancel, string errorInfo);
    public delegate void OnGotFBFriendInGame(string resultJsonStr);
    public delegate void OnGotFBMyInfo(string resultJsonStr);
    public delegate void OnFBInvitedSucceed(string resultJsonStr);
    private static string appLinkUrl;

    public static void Init()
    {
        FB.Init(() =>
        {
            Debug.Log("FB OnInitComplete!");
            Debug.Log("FB.AppId: " + FB.AppId);
            Debug.Log("FB.GraphApiVersion: " + FB.GraphApiVersion);
            //獲取應用連結
            FBGetAPPLinkUrl();

        }, (isUnityShutDown) =>
        {
            Debug.Log("FB OnHideUnity: " + isUnityShutDown);
        });
    }

    public static void FBLogin(OnFBLoginSucced onFBLoginSucced = null, OnFBLoginFaild onFBLoginFaild = null)
    {
        var perms = new List<string>() { "public_profile", "email", "user_friends" };
        FB.LogInWithReadPermissions(perms, (result) => 
        {
            if (FB.IsLoggedIn)
            {
                Debug.Log("FBLoginSucceed");
                if (onFBLoginSucced != null)
                {
                    onFBLoginSucced(Facebook.Unity.AccessToken.CurrentAccessToken);
                }
            }
            else
            {
                Debug.Log("FBLoginFaild");
                Debug.Log(result.RawResult);
                if (onFBLoginFaild != null)
                {
                    onFBLoginFaild(result.Cancelled, result.Error);
                }
            }
        });
    }

    //分享, 例:
    //uri = "https://developers.facebook.com/";
    //contentTitle = "ShareLink";
    //contentDesc = "Look I'm sharing a link";
    //picUri = "https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/holiday/habo/res/doodle/3.png";

    public static void FBShareLink(string uri, string contentTitle, string contentDesc, string picUri, OnFBShareLinkSucced onFBShareLinkSucced = null, OnFBShareLinkFaild onFBShareLinkFaild = null)
    {
        FBShareLink(new Uri(uri), contentTitle, contentDesc, new Uri(picUri), onFBShareLinkSucced, onFBShareLinkFaild);
    }

    private static void FBShareLink(Uri uri, string contentTitle, string contentDesc, Uri picUri, OnFBShareLinkSucced onFBShareLinkSucced = null, OnFBShareLinkFaild onFBShareLinkFaild = null)
    {
        FB.ShareLink(uri, contentTitle, contentDesc, picUri, (result) =>
        {
            if (result.Cancelled || !String.IsNullOrEmpty(result.Error))
            {
                Debug.Log("ShareLink Faild");
                if (onFBShareLinkFaild != null)
                {
                    onFBShareLinkFaild(result.Cancelled, result.Error);
                }
            }
            else
            {
                Debug.Log("ShareLink success!");
                if (onFBShareLinkSucced != null)
                {
                    onFBShareLinkSucced(String.IsNullOrEmpty(result.PostId) ? "" : result.PostId);
                }
            }
        });
    }

    //獲取自己的資訊
    public static void GetMyInfo(OnGotFBMyInfo onGotFBMyInfo)
    {
        if (FB.IsLoggedIn == false)
        {
            UIFloatTip.Create("Not Login in");
            return;
        }
        FB.API("me?fields=id,name,picture", HttpMethod.GET, (result) => {
            Debug.Log(result.RawResult);
            if (onGotFBMyInfo != null)
            {
                onGotFBMyInfo(result.RawResult);
            }
        });
    }

    //獲取遊戲好友
    public static void GetFBFriendInGame(OnGotFBFriendInGame onGotFBFriendInGame = null)
    {
        Debug.Log("GetFBFriendInGame");
        if (FB.IsLoggedIn == false)
        {
            UIFloatTip.Create("Not Login in");
            return;
        }

        FB.API("me/friends?fields=id,name,picture", HttpMethod.GET, (result)=> {
            Debug.Log(result.RawResult);
            if (onGotFBFriendInGame != null)
            {
                onGotFBFriendInGame(result.RawResult);
            }
        });
    }

    //獲取可邀請好友, 獲取失敗 TODO
    public static void GetFBFriendInvitable()
    {
        if (FB.IsLoggedIn == false)
        {
            UIFloatTip.Create("Not Login in");
            return;
        }
        FB.API("/me/invitable_friends?fields=id,name,picture", HttpMethod.GET, (result) => {
            Debug.Log("result: ");
            Debug.Log(result.RawResult);
        });
    }

    //邀請, 
    public static void FBInvite(string assignedLink, string previewImageUrl, OnFBInvitedSucceed onFBInvitedSucceed = null)
    {
        if (String.IsNullOrEmpty(assignedLink))
        {
            assignedLink = appLinkUrl;
        }
        Debug.Log("appLinkUrl: " + appLinkUrl);
        Debug.Log("assignedLink: " + assignedLink);
        FBInvite(new Uri(assignedLink), new Uri(previewImageUrl), onFBInvitedSucceed);
    }

    private static void FBInvite(Uri appLinkUrl, Uri previewImageUrl = null, OnFBInvitedSucceed onFBInvitedSucceed = null)
    {
        FB.Mobile.AppInvite(appLinkUrl, previewImageUrl, (result)=> {
            Debug.Log("rawResult: " + result.RawResult);
        });
    }

    //獲取APPLink, 獲取失敗,TODO
    public static void FBGetAPPLinkUrl()
    {
        FB.GetAppLink((result)=> {
            Debug.Log(result.RawResult);
            Debug.Log("Ref: " + result.Ref);
            Debug.Log("TargetUrl: " + result.TargetUrl);
            Debug.Log("Url: " + result.Url);
            appLinkUrl = result.Url;
        });
    }
}