유니티와 페이스북 연동하기 (2/3)
원문 보기
1편 튜토리얼 보기
(역자 주 : 본 튜토리얼에서 예제를 따라하기위해 php, mysql, PHPMyAdmin등 여러 설치할 것들이 있습니다. 그래서 이를 처음으로 접하시는 분들에게는 중간중간 어려움을 겪을 수도 있지만, 이번 기회에 설치법과 간단한 사용법을 익힐 수 있는 좋은 예제라고 생각되니 한번 해보시면 많은 도움이 될 것입니다.)
시작하기 전에 알아야할 것: 이 글은 유니티에서 페이스북을 연동시키는 튜토리얼이다. 이는 자신의 웹-앱에 페이스북을 연결하고 싶어하는 유니티 개발자를 위한 기술 가이드이다. 만약 이 주제가 흥미롭게 들린다면, 주저없이 한번 읽어 보자.
두번째 튜토리얼에서 배울 내용은 다음과 같다:
- 점수를 보내고 저장하는 방법
- 점수를 받아오는 방법
- 점수와 페이스북 프로필 사진을 출력하는 방법
게임 만들기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class DiceGame : MonoBehaviour { public static string FacebookId = "1"; //We'll link up with FacebookManager later. private const int max = 6; //Max score, the sides on the dice private string btnText = "Press to roll"; void OnGUI() { if (GUI.Button(new Rect(10, 10, 200, 50), btnText)) { int score = UnityEngine.Random.Range(1, max + 1); //Calculate our score. btnText = string.Format("You rolled {0}, \nclick to try again.", score); StartCoroutine(submitHighscore(score, FacebookId)); } } IEnumerator submitHighscore(int score, string fbid) { yield return null; //We'll implement this later. } } |
어려운 건 없다. 단지, 무작위 숫자를 생성하는 버튼을 누르면, submitHighsocre 코루틴을 시작한다. 이 함수는 점수를 넣기 위해서 웹 요청을 해야하는데 일단 웹서비스를 만들어 보자!
웹서비스 만들기
페이스 북 id, 점수 그리고 만들어진 날짜까지 저장할 것이다. PHPMyadmin을 이용해서 "highscore"라는 이름으로 데이터베이스를 만들자:
(역자 주 : PHPMyadmin은 웹상에서 MySQLDB를 관리할 수 있게 도와주는 오픈 소스 도구입니다.
이를 실행하기 위해서는 서버에 MySQL에 PHP가 설치되어 있어야 합니다 . 자세한 설명은 관련 블로그 링크로 대신하겠습니다. Apache & PHP & MySql설치, PHPMyadmin설치)
1 2 3 4 5 6 | CREATE TABLE `highscores`.`scores` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `fbid` TEXT NOT NULL , `score` INT NOT NULL , `creation_date` TIMESTAMP NOT NULL ) ENGINE = INNODB; |
이제 우리는 데이터 베이스 설정을 했고, 점수를 넣는 스크립트를 만들어 보자. 새롭게 "insert_highscore.php"라는 이름의 파일을 만들어
(역자 주 : www 디렉토리는 apache 서버일경우 htdocs폴더를 의미합니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php mysql_connect('localhost','root',''); //Connect to the databsae mysql_select_db('highscores'); $score = @$_GET['score']; $fbid = @$_GET['fbid']; if(!$score || !$fbid) //Ensure both parameters are passed die("No fbid or score"); mysql_query("INSERT INTO scores (fbid, score) VALUES ('$fbid', $score)"); //Execute the query ?> |
첫 두번째 라인은 데이터베이스에 연결을 해서 적절한 데이터베이스를 선택한다. 다음, 입력을 검사해서 score와 fbid가 제공되지 않으면, 실행을 멈춘다. 확인을 한 후에, 이 값들을 SQL을 사용하여 데이터베이스에 넣을 것이다. 좋다, 이제 http://localhost/insert_highscore.php?fbid=4&score=1로 방문해보자. phpMyAdmin을 이용해서 highscore 데이터베이스에있는 score 테이블에 새로운 행이 생겼는지 확인해라.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php mysql_connect('localhost','root',''); mysql_select_db('highscores'); $scoresQuery = mysql_query("SELECT MAX(score) as max_score, fbid FROM scores GROUP BY fbid ORDER BY max_score DESC"); while($scoresRow = mysql_fetch_assoc($scoresQuery)) echo $scoresRow['fbid'] . ',' . $scoresRow['max_score'] . "<br />\n"; ?> |
fbid,score
fbid,score
etc..
http://localhost/get_highscores.php를 실행해서 확인해보자. 만약 더 많은 점수가 필요하다면 insert_highscore.php를 다시 사용하면 된다.
데이터 삽입하기
DiceGame 스크립트에 다음 소스를 추가해보자.
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 | private Dictionary<string, int> scores; //The key is the facebook id, value is his score. void Start() { scores = new Dictionary<string, int>(); StartCoroutine(retrieveHighscores()); //Start out by getting the current scores. } IEnumerator submitHighscore(int score, string fbid) { WWW webRequest = new WWW("http://localhost/insert_highscore.php?score=" + score + "&fbid=" + fbid); yield return webRequest; yield return StartCoroutine(retrieveHighscores()); //After we submit we'd want an update, perhaps someone else played too! } IEnumerator retrieveHighscores() { WWW webRequest = new WWW("http://localhost/get_highscores.php"); yield return webRequest; string[] lines = webRequest.text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); //Split the response by newlines. scores = new Dictionary<string, int>(); //Always reset our scores, as we just got new ones. foreach (string line in lines) //Parse every line { string[] parts = line.Split(','); string id = parts[0]; int score = int.Parse(parts[1]); scores.Add(id,score); } } |
좋다, 우리는 유니티 내장된 WWW클래스와 적절한 GET 매개변수를 이용해서 웹페이지를 호출할 것이다. highscores를 웹으로 보낼 때마다, 자동적으로 새로운 highscores 값들을 받을 것이다. retrieveHighscores함수안에 파싱을 하는 부분이 다시 나오는데, 받은 highscores들의 값을 매 행으로 구분한 다음, ','(콤마)로 다시 구분할 것이다.
이 스크립트를 씬에 있는 게임 오브젝트에 넣어, 유니티 에디터안에서 실행을 해보자. 버튼을 누르면, 약간의 시간이 지나고 나서 적절하게 작동하는 것을 볼 수 있을 것이다. 데이터베이스에 새로운 행이 추가 되었는지 확인을 해보자.
페이스북에 연결하기
이제 ID를 받아오기 위해 FacebookManager 스크립트를 만들자:
1 2 3 4 5 6 7 8 9 10 11 | public class FacebookManager : MonoBehaviour { void Start() { Application.ExternalCall("GetCurrentUser"); } public void GetCurrentUserComplete(string fbid) { DiceGame.FacebookId = fbid; } } |
"FacebookManager"라는 게임 오브젝트를 만들어 FacebookManager스크립트를 붙이고 웹으로 빌드를 하자.
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 | <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', 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(); }); }; function GetCurrentUser() //When we are logged in this shows our name. { FB.api('/me', function(meResponse) //Do a graph request to /me { getUnity().SendMessage("FacebookManager", //Game object name, make sure this exists! "GetCurrentUserComplete", //Method to call meResponse.id); //Our serialized facebook data }); } //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 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> |
페이지를 열고, 여러번 버튼을 눌러보자. 그리고 데이터베이스에가면 당신의 Facebook ID가 삽입된 것을 볼 수있을 것이다.
: http://graph.facebook.com/UID/picture/
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 | private Dictionary<string, Texture2D> fbProfileImages = new Dictionary<string, Texture2D>(); IEnumerator retrieveHighscores() { WWW webRequest = new WWW("http://localhost/get_highscores.php"); yield return webRequest; string[] lines = webRequest.text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); scores = new Dictionary<string, int>(); //Always reset our scores, as we just got new ones. foreach (string line in lines) { string[] parts = line.Split(','); string id = parts[0]; int score = int.Parse(parts[1]); if (!fbProfileImages.ContainsKey(id)) //Have we already loaded this user before? { //No, better get our image! WWW imageRequest = new WWW("http://graph.facebook.com/" + id + "/picture"); yield return imageRequest; fbProfileImages.Add(id, imageRequest.texture); } scores.Add(id,score); } } |
OnGUI는 다음과 같이 변경하자:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void OnGUI() { if (GUI.Button(new Rect(10, 10, 200, 50), btnText)) { int score = UnityEngine.Random.Range(1, max + 1); btnText = string.Format("You rolled {0}, \nclick to try again.", score); StartCoroutine(submitHighscore(score, FacebookId)); } float h = 10; foreach (var score in scores) { GUI.Label(new Rect(300, h, 200, 50), score.Value.ToString()); if (fbProfileImages != null && fbProfileImages.ContainsKey(score.Key)) GUI.DrawTexture(new Rect(230, h, 50, 50), fbProfileImages[score.Key]); h += 60; } } |
fbProfileImages dictionary는 프로필 텍스쳐를 가지고 있는데, 새로운 유저가 발견될 때 마다, 새롭게 로드될 것이
다. 빌드를 하고 프로젝트를 다시 실행시켜 보자. 페이스북에서 프로필 사진을 가져오는 것이 이렇게 쉬울줄은 몰
랐을 것이다 :)
결과는 훌륭하지만, 여기 약간 수상한 부분이 있다. 마크 주커버그가 주사위 굴리기에서 7의 값을 가지고 있다!
다음 튜토리얼에서는 어떻게 이런 결과가 나오는지 찾아낼 것이고, 악의적인 유저들에의한 공격를 방어하는 방법을 배울 것이다.