본문 바로가기

유니티 개발 정보/강좌

유니티와 페이스북 연동하기 (1/3)

원문 보기

시작에 앞서

시작하기 전에 알아야할 것:  이 글은 유니티에서 페이스북을 연동시키는 튜토리얼이다. 이는 자신의 웹-앱에 페이스북을 연결하고 싶어하는 유니티 개발자를 위한 기술 가이드이다. 만약 이 주제가 흥미롭게 들린다면, 주저없이 한번 읽어 보자.
Paladin사의 게임들은 플레이어가 페이스북을 사용하여 친구들과 함께 플레이할 수 있다. 3개의 연재 글을 통해 어떠한 방법으로 유니티 어플리케이션을 페이스북과 연동하고, 친구들의 점수를 보며, 우리의 앱을 보호할 수 있는지를 배우게 될 것이다.

첫 번째 글에서, 우리는 현재 유저의 친구와 그들의 이름을 유니티에 표시하기 위해, 자바 스크립트 SDK를 사용하는 Facebook 어플리케이션을 만들 것이다. 이 튜토리얼은 웹관련 배경지식이 조금 필요하고, 유니티와 C#을 잘 이해하고 있어야 한다. 우리가 만들고자하는 최종 결과물을 알고 싶다면 이곳을 클릭해라

어플리케이션과 개발환경 설정하기

시작에 앞서, 당신의 어플리케이션을 페이스북에 등록해야 한다. 이를 위해서는 "개발자 계정"이 필요한데, 이를 만들기 위해서는 당신의 전화번호가 필요하다. 어플리케이션을 만든 다음, 페이스북에 어플리케이션의 웹페이지를 알려줘야 한다. 우선, 웹 사이트의 주소를 http://localhost/로 설정하자.(밑에 그림 참고) 이는 로컬상에서 당신의 어플리케이션을 테스트할 수 있게 해준다. 그 다음에는 Advanced 탭에 있는 Sandbox 모드를 설정해야 한다. 이 모드를 켜면, 오직 개발자만이 어플리케이션을 볼 수 있다. 이는 어플리케이션을 개발하는데 유용하다. 그러나 개발을 하고 나서, 이것을 끄는 것도 잊지 말자.


우리는 로컬상에 개발을 하려고 하기 때문에, 자신의 컴퓨터에서 웹서버가 구동되기를 원한다. 만약 웹서버가 설치되지 않았다면, Wampserver 나 XAMPP같은 간단한 패키지를 사용해라. 웹 서버가 잘 작동하는지 확인하기 위해 브라우저를 열어 주소창에 http://localhost라고 입력해보자. 잘 작동하면 "It Works"라고 적힌 글자가 뜰 것이다. 우리의 경우에는 PHP를 이용해서 서버를 구축했는데, 만약 다른 기술(ASP, ROR 기타등)이 편하다면, 그것을 사용하는 것도 무방하다.

Facebook SDK 분석하기

이제, 설정을 했으니, Facebook API를 가지고 놀아보자. 페이스북 그래프와 친숙해지기 위해서, 우리가 원하는 정보를 가지고 있는 간단한 페이지를 만들어 보자. 페이스북은 그래프를 사용하여 유저가 로그인되어있고, 적당히 정보를 공개해놓았다면, 손쉽게 유저의 모든 정보에 할 수 있다. 우리는 이와 관련된 문서를 자세히 읽어보는 것을 강력히 추천한다.우리는 자바스크립트 SDK를 사용할 것인데, 이 문서를 반드시 읽어야 한다. 예제에서, 우리는 현재의 사용자 ID와 이름 그리고 그의 친구들의 목록을 얻어야 한다. 당신의 www-root에 다음의 내용이 포함되어 있는 html 페이지를 만들어라.
(역자 주 : 밑에 코드에서 FB.init()에서 appId를 자신의 어플리케이션 번호로 수정해야 한다.
밑에 있는 '171298766297727'는 임시 번호 이다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject.js"></script>
<div id="fb-root"></div> <!-- Required by Facebook -->
 
<script type='text/javascript'>
 
    //Fired when the facebook sdk has loaded
    window.fbAsyncInit = function()
    {
        FB.init(
        {
          appId      : '171298766297727', // application ID
          status     : true, // check login status
          cookie     : true, // enable cookies to allow the server to access the session
          oauth      : true, // enable OAuth 2.0
          xfbml      : false // dont parse XFBML
        });
 
        //Get the current login status.
        FB.getLoginStatus(function(loginStatusResponse)
        {
            if(loginStatusResponse.authResponse) //There is an authresponse, the user is already logged in and authenticated
            {
                logUserName();
                logFriends();
 
            } else { //The user was not logged in, allow him to.
                FB.login(function(loginResponse)
                {
                    if(loginResponse.authRespsonse) //Did he login successfully?
                    {
                        logUserName();
                        logFriends();
                    }
                });
            }
        });
 
        function logUserName() //When we are logged in this shows our name.
        {
            FB.api('/me'function(meResponse)  //Do a graph request to /me
            {
                alert(meResponse.id + " " + meResponse.first_name); //Show the response
            });
        }
 
        function logFriends()   //When we are logged in this shows our friends.
        {
            FB.api('/me/friends'function(friendResponse) //Do a graph request to my friends.
            {
                for(var i = 0; i < friendResponse.data.length; i++) //Loop over all my friends
                    alert(friendResponse.data[i].id + " " + friendResponse.data[i].name);
            });
        }
 
    };
 
    //Load the Facebook JS SDK
    (function(d){
     var js, id = 'facebook-jssdk'if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     d.getElementsByTagName('head')[0].appendChild(js);
    }(document));
 
</script>



페이스북 라이브러리를 불러온 후에, 현재 유저의 상태를 확인하고, 아직 로그인되지 않았다면 로그인을 제공할 것이다. 로그인이 된 것을 확인하면, 우리는 현재 유저의 정보를 얻기 위해서 "/me"에게 그래프 요청을 사용한다. 그리고 나서, "/me/friends"를 요청함으로써, 유저의 친구들을 얻는다. Firebug같은 자바스크립트 디버거를 사용해보자. 그리고 어떻게 작동하고, FaceBook Api의 요청에 어떻게 반응이 오는지 이해하기 위해서, 단계별로 코드를 살펴보자.

유니티로 가져오기

이제, 우리의 웹페이지에서 원하는 정보들을 가지고 있다. 이를 유니티로 전달해보자! 유니티의 레퍼런스 메뉴얼은 어떻게 기본적인 메세지를 게임으로 보내는지 설명이 잘 되어 있다. 페이스북의 정보를 얻어오는 HTML 페이지를 요청하는 버튼을 만들어보자. 새로운 유니티 프로젝트를 만들고 FacebookManager 스크립트를 만들어 다음의 소스를 입력하자:

1
2
3
4
5
6
7
    void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 100, 24), "Get info"))
            Application.ExternalCall("GetCurrentUser")
        if (GUI.Button(new Rect(10, 44, 100, 24), "Get friends"))
            Application.ExternalCall("GetUserFriends")
    }
"Get info"버튼을 누르면 자바스크립트 함수 "GetCurrentUser"가 호출된다. 아주 간단하다. 우리는 이미 어떻게 Facebook으로부터 정보를 얻는지 알고 있고, 이제 우리가 해야 할 일은 이 데이터들을 게임에 전달하는 것이다. SendMessage로 적절한 게임오브젝트와 메소드를 호출함으로써 이를 구현할 것이다. 그러나 문제점이 하나 있는데, SendMessage는 하나의 매개변수만을 보낼 수 있다. 이는 약간의 문제를 초래하는데, 우리는 유저의 아이디와 이름을 보내야 하기 때문이다. 그러므로 두 개의 매개변수를 전달하기 위한 방법을 찾아야 한다. 큰 데이터 구조체를 위해 나는 강력히 JSON을 사용하는 것을 권한다. 그러나 이 예제는 간단하기 때문에, 다음과 같은 방법으로 이 문제를 해결할 것이다.
위에서 만들었던 기본페이지를 우리가 사용할 페이지로 다시 작성해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject.js"></script>
<div id="fb-root"></div>
 
<script type='text/javascript'>
 
    //Fired when the facebook sdk has loaded
    window.fbAsyncInit = function()
    {
        FB.init(
        {
          appId      : '171298766297727'// application ID
          status     : true, // check login status
          cookie     : true, // enable cookies to allow the server to access the session
          oauth      : true, // enable OAuth 2.0
          xfbml      : false // dont parse XFBML
        });
 
        //Get the current login status.
        FB.getLoginStatus(function(loginStatusResponse)
        {
            if(!loginStatusResponse.authResponse) //Not logged in, log him in
                FB.login();
        });
    };
 
    //Load the Facebook JS SDK
    (function(d){
     var js, id = 'facebook-jssdk'if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     d.getElementsByTagName('head')[0].appendChild(js);
    }(document));
 
 
    function GetCurrentUser() //When we are logged in this shows our name.
    {
        FB.api('/me'function(meResponse)    //Do a graph request to /me
        {
            var fbdata = meResponse.id + "," + meResponse.first_name; //As per our format, 'id,name;'
 
            getUnity().SendMessage("FacebookManager"//Game object name, make sure this exists!
                                    "GetCurrentUserComplete"//Method to call
                                    fbdata); //Our serialized facebook data
        });
    }
 
    function GetUserFriends()
    {
        FB.api('/me/friends'function(friendResponse)
        {
            var fbdata;
 
            for(var i = 0; i < friendResponse.data.length; i++) //Loop over all my friends
                fbdata += friendResponse.data[i].id + "," + friendResponse.data[i].name + ';';
 
            getUnity().SendMessage("FacebookManager",
                                    "GetFriendsComplete",
                                    fbdata);
        });
    }
 
 
    function getUnity()
    {
        if (typeof unityObject != "undefined")
        {
            return unityObject.getObjectById("unityPlayer");
        }
        return null;
    }
    if (typeof unityObject != "undefined")
    {
        unityObject.embedUnity("unityPlayer""WebPlayer.unity3d", 960, 640);
    }
</script>
 
<div id='unityPlayer'></div>

유저가 요청을 거절하거나, 그래프 요청이 실패한 경우, 추가적인 작업을 해야하지만, 이는 이번 튜토리얼 범위에 벗어나기 때문에 다루지 않을 것이다.
페이지에서 데이터를 받았고, 이제 게임으로 보낼 수 있는지 확인해 보자. 이를 FacebookManager스크립트에 추가하고 "FacebookManager"라는 이름을 가진 게임 오브젝트에 붙이자
(역자 주 : 위에 있는 웹페이지 html파일과 유니티를 웹플레이어로 빌드해서 나온 xxxxx.unity3d파일을 웹서버가 구동되는 폴더에 함께 있어야 한다. 그리고 위에 unityObject.embedUnity()에서 두번째 파라미터를 xxxxx.unity3d로 반드시 바꿔야한다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
private string user_id; //Facebook id
private string user_name; //User name
private Dictionary<stringstring> friends; //All the users friends key = id, value = name
 
public void GetCurrentUserComplete(string fbdata) //Called by js when the userinfo was retrieved. fbdata looks like 1234,name
{
    string[] parts = fbdata.Split(',');
    user_id = parts[0];
    user_name = parts[1];
}
public void GetFriendsComplete(string fbdata) //Called by js when the friends are retrieved. fbdata looks like 1234,name;5678,name;..
{
    friends = new Dictionary<stringstring>();
 
    string[] parts = fbdata.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); //we've seperated each user, now get their id and name
 
    foreach (string user in parts)
    {
        string[] userInfo = user.Split(','); //Split each user on ',' first should be id then name.
 
        friends.Add(userInfo[0], userInfo[1]);
    }
}
 
void OnGUI()
{
    if (GUI.Button(new Rect(10, 10, 100, 24), "Get info"))
        Application.ExternalCall("GetCurrentUser");
    if (GUI.Button(new Rect(10, 44, 100, 24), "Get friends"))
        Application.ExternalCall("GetUserFriends");
 
    GUI.Label(new Rect(200, 10, 200, 24), user_name); //Display name
 
    if (friends != null//If we retrieved our friends already
    {
        float h = 10;
        foreach (var friend in friends)
        {
            GUI.Label(new Rect(200, 10 + i * 24, 200, 24), friend.Value);
            h += 24;
        }
    }
 }
코드는 반드시 코드 그 자체로 이해가 되어야 한다. 파싱하는 부분은 약간 까다로운데, 에러가 발생하기 쉽다. 모든 예측할 수 없는 입력은 어플리케이션에 에러를 발생시킬 것이다. 만약 무슨 일이 발생할지 확신할 수 없다면, 중단점을 설정하고, Debug.Log를 사용해서 문제점을 파악하자. 문제가 발생할 때마다 이렇게 대응해야 한다. 화면에는 현재 이름과, 친구의 이름이 나타날 것이다.

좋다, 이제 우리는 페이스북 개발 환경을 설정하는 방법과, 기본적인 그래프 API 호출 그리고 이 응답을 유니티에 보내는 방법을 알게 되었다. 이것을 토대로, 어떻게 유니티로 담벼락 다이얼로그를 열수 있는지 생각해 보자.
본 강좌는 3개의 튜토리얼로 이루어져 있다. 만약 조금 더 배우고 싶다면, 다음 강좌를 확인해보라.

파트2

  • 점수를 보내고 저장하는 방법
  • 점수를 검색하는 방법
  • 점수와 페이스북 프로필 사진을 출력하는 방법

파트3

  • 점수를 수정하는 방법
  • 유저가 자신의 점수를 수정하는 것을 방지하는 방법