2019. 10. 4. 18:24

 

안녕하세요. 게임개발자 놀이터 입니다.

 

이전 포스팅에 이어 웹크롤링에 대해서 포스팅 하고자 합니다

 

웹에서 정보 가져오기 - 1

 

저번에 requests 설정까지 마무리 했습니다.

 

그럼 이제 requests가 정상 작동하는지 확인해봅시다.

 

 

이와 같이 소스를 입력 한 후 빌드 ( 컨트롤 + 쉬프트 + B ) 를 해봅시다.

 

 

status_code 값과 OK 값이 200, true가 나온다면 성공입니다.

 

하지만 html 텍스트는 현재 읽을 수 없습니다.

 

html을 읽기 위해선 다음과 같은 세팅이 필요합니다.

 

BeautifulSoup

 

html의 내용을 파이썬에서 사용할 수 있도록 파싱 해주는 패키지 입니다.

 

명령 프롬프트 창을 이용해 bs4를 설치 해줍니다.

 

 

 

이제 html을 파싱할 수 있습니다.

 

 

위처럼 소스를 입력하고 빌드하시면 HTML 소스가 로그창에 출력 된걸 확인 하실 수 있습니다.

 

데이터 검색 

 

테스트에 사용 할 HTML  URL입니다. :  https://www.google.com/search?q=+site:tistory.com+%EC%8B%9C%EB%A6%AC%EC%8B%9C%EC%95%88&sa=X&ved=2ahUKEwjuofzmjoLlAhWUE4gKHS-wAYEQrAN6BAgGEBQ&biw=2048&bih=1042

구글 페이지에서 [site:tistory.com 시리시안] 을 검색한 URL입니다.

 

 

 

이곳에서 저는 검색 제목만 모아서 크롤링 해보려 합니다.

 

크롬에서는 검사 기능을 통해 바로 HTML을 볼 수 있습니다.

 

찾고자 하는 글에 우클릭 후 검사를 눌러 줍니다.

검사를 누르면 우측에 HTML 창이 뜨게 됩니다.

 

 

내용을 보니 저 검색결과는 div 태그에 class 'ellip'를 가지고 있군요. 이 정보를 이용해 파싱해 찾아 봅시다.

 

 

전체 소스입니다. 중간에 잘린 url은 위에 적용된 HTML입니다.

 

빌드 해보니 아무런 결과가 나오지 않았습니다. 아무래도 클래스 명칭 'ellip' 로 찾는게 문제 인거 같네요.

 

정확한 HTML 비교를 위해 prettify() 로 HTML을 출력 해봤습니다.

 

클래스 명칭이 다르네요, 아무래도 검색할때 생성되는 구조이거나 랜덤으로 만들어지는거 같습니다. 따라서 클래스 비교 방식은 사용 할 수 없겠군요.

 

이번엔 글 제목을 클릭해서 들어 갈 수 있으니, a 태그로 찾은 후 div로 분류해봤습니다.

 

 

출력되는 list2를 확인해보니 아래와 같았습니다.

 

 

첫번째 검색결과와 제가 필요했던 애들의 클래스 명칭이 전부 똑같네요. 이건 이용할 수 있을꺼같습니다.

 

 

첫번째 클래스 명칭을 이용해 찾도록 수정했습니다.

 

 

제가 얻고자 했던 목록들만 얻을 수 있게 되었습니다.

 

이처럼 크롬의 HTML을 분석하여 원하는 정보를 찾을 수 있습니다. 구글의 경우 위와 같았지만, 다른 사이트의 경우엔 분석이 우선시 되니, HTML 을 읽는 기술이 필요할꺼 같습니다.

 

감사합니다.

 

 

Posted by 시리시안

댓글을 달아 주세요

  1. Favicon of http://tvple.me/ BlogIcon 티비다시보기 2020.07.03 16:55  댓글주소  수정/삭제  댓글쓰기

    잘 보고 갑니다~~

2019. 10. 4. 16:45

 

안녕하세요. 게임개발자 놀이터 입니다.

 

웹크롤링에 대해서 포스팅 하고자 합니다

 

웹 크롤러

 

우리가 어떤 정보를 웹 브라우저로만 보는 것이 아니라, 그 정보 들을 내가 이용하기 편한 방식(XML, JSON) 등으로 DB에 쌓아두고 싶을 때가 있습니다.

웹 데이터를 원하는 방식으로 가공하여 저장하는 기능을 웹크롤링 한다고 합니다.

 

웹에서 정보 가져오기 - 1

 

php 의 requests 라는 라이브러리를 이용해서 웹의 정보를 가져옵니다.

 

설치하기 위해선 pip를 이용합니다.

 

[Window+R]  + cmd 를 이용해 명령 프롬프트를 엽니다.

 

사용자 PC에 php가 설치되어 있는 폴더로 이동합니다.

 

폴더 안에 Scripts 폴더까지 이동합니다.

 

저의 경우는 C:\Python27\Scripts 입니다.

 

그후, pip install requests를 입력합니다. 아래 화면 처럼 뜬다면 성공입니다.

(pip 업그레이드 문구는 무시해주세요 )

 

 

제대로 설치 되었는지 확인을 위해 ATOM 에디터로 넘어와 임포트 해봅니다.

 

ATOM Python 모듈 설정

 

ATOM에서 pip로 설치한 모듈을 사용하려면 추가로 설정해줘야 합니다.

 

우리는 '파이썬 프로그래밍 -01 ATOM 설치 (Python)' 에서 ATOM 플러그인으로 'script'를 설치 했습니다.

 

모듈을 내장하여 빌드 하기 위해선 'script'플러그인은 조금 수정 해줘야 합니다.

 

우선 [컨트롤 + ,]을 눌러 settings 창을 엽니다.

그후, 좌측 Packages 메뉴를 누른후 Installed Packages 에서 'script'를 검색한 후 Settings를 눌러 줍니다.

 

그러면 'script'의 설정 창이 열리게 되는데, [View Code]를 눌러 줍니다.

 

ViewCode를 누르면 아톰창이 새로 열리게 됩니다.

 

그후 왼쪽 프로젝트 목록에서

 

[ script / lib / grammars / python.coffee ]를 열어 줍니다.

 

 

 

python 으로 되어있는 경로를 각각 파이썬 경로로 수정해줍니다.

 

저의 경우는 [ C:/Python27/python ] 입니다.

 

 

이후 창을 닫은 후, 메인 소스에 requests를 임포트 하는 코드를 작성 한 후 빌드 해보면

 

 

 

아무런 에러 없이 완료 된다면 성공입니다.

 

감사합니다.

 

이후 내용은 다음 포스팅에서 진행 하겠습니다.

 

 

 

 

 

 

 

 

 

 

 

Posted by 시리시안

댓글을 달아 주세요

2019. 10. 4. 15:45

 

안녕하세요. 게임개발자 놀이터 입니다.

 

ATOM으로 python 프로그래밍 중 에러가 발생하여 해결법을 포스팅 하려합니다.

 

먼저 에러 로그는 다음과 같습니다.

 

UnicodeEncodeError: 'cp949' codec can't encode character '\xa0' in position 63430: illegal multibyte sequence

 

유니코드 관련 에러로 확인됩니다.

 

ATOM의 우하단을 확인해봅시다.

 

 

해당 인코딩 방식이 UTF-8 인지 확인합니다.

 

만약 UTF-8이 아니라면, UTF-8로 변경 후 다시 시도해봅니다.

 

이미 UTF-8 이거나, 에러가 계속 된다면

 

 

해당 소스를 최상단에 추가 해주면 됩니다.

 

감사합니다

 

 

Posted by 시리시안

댓글을 달아 주세요

2019. 10. 4. 12:08

안녕하세요. 게임개발자 놀이터 입니다.

 

이번에 웹 크롤링을 해야 하는 이슈가 생겼는데, 기존 언어보다 Python이 강력하다는 이야기를 듣고, 파이썬으로 진행 하며 정리 해보려합니다.

 

먼저 파이썬 프로그램을 만들고 편집 할 수 있는 'ATOM Text Editor' 설치입니다.

 

아톰은 텍스트 에디터 기능 뿐만이 아닌 패키지 설치로 파이썬, C, Nodejs 등 여러 언어를 지원하여 상당히 편리합니다.

 

이제, 아톰을 설치해 보도록 하겠습니다.

 

먼저 아톰 공식 웹사이트에 들어갑니다.

 

 

윈도우 1.40.1 버전 다운로드를 클릭합니다.

 

클릭시 자동으로 다운로드가 시작됩니다. 적은 용량으로 바로 다운로드가 완료됩니다.

 

 

클릭시 아톰 특유의

 

 

우주선의 짐을 싦는 모습이 나옵니다. 조금만 기다리시면 자동으로 실행됩니다.

 

아톰이 설치 완료되면 화면 중앙에 아래와 같은 메뉴가 보입니다.

 

먼저 패키지 설치를 위해 아래 버튼을 클릭해줍니다.

 

 

그 후 파이썬 설치를 위해 autocomlite-python을 검색해 설치 해줍니다.

 

 

아래와 같이 자동생성 기능이 포함되어 있어 상당히 편리 합니다.

 

 

다시 인스톨 화면으로 돌아와서 이번엔 빌드를 위한 script를 검색해서 설치해줍니다.

 

여러 소스를 빌드할 수 있도록 해주는 패키지입니다.

 

 

 

설치가 완료된 후, 우측 프로젝트를 우클릭하여 New File 하여 파일을 하나 생성해줍니다.

 

 

확장자 (.py)을 입력하지 않으면, 파이썬 파일로 인식하지 않습니다. 꼭 입력해주세요.

 

 

해당 파일에 아래처럼 print문을 입력한 후

 

상단 메뉴에서 Packages - Script - Run Script ( 단축키 Ctrl + Shift + B ) 를 누르시면 소스가 실행됩니다.

 

하단 로그에 아래와 같이 글이 뜬다면 성공입니다.

 

 

이로써 파이썬 환경 개발을 위한 기초 세팅이 끝났습니다.

 

제가 잘 아는 부분이 아니라, 개발하면서 나온 화면을 촬영후 글을 작성했습니다. 댓글 달아주시면 최대한 응답해드리겠습니다.

 

감사합니다.

 

 

Posted by 시리시안

댓글을 달아 주세요

2019. 3. 28. 14:35
 
안녕하세요. 게임개발자 놀이터 입니다.
 
유니티에서 WWW클래스 사용시 header 및 body 관리 방법에 대해 포스팅 하고자 합니다
 
www 클래스에서 body를 넣을땐 WWWForm 클래스를 주로 이용하게됩니다.
 
 
이처럼 바디를 WWWForm 이용해 넣다 보니, 헤더도 똑같이 WWWForm 안에서 찾게 됩니다.
 
WWWForm안에는 headers 라는 Directionary 가 있고. 그 안엔 Add 함수가 있습니다.
따라서 이렇게 짜는 경우가 많습니다.
 
 
하지만 이건 작동하지 않죠...
 
그 이유는 WWWForm.headers 변수는 읽기 전용이기 때문에. 
Add 함수를 호출해도 아무 것도 추가하지 않습니다.
 
따라서 다른 방법으로 Header 값을 추가해야 합니다.
 WWW 클래스를 만들때, 바이너리 데이터와 함께 Header를 넣어주는 생성자가 있습니다. 
 
 
그곳에 이처럼 넣어주면 헤더가 정상적으로 들어가게 됩니다.
 
또 헤더와 바디를 같이 넣어줘야 하는 경우에는
 
 
이처럼 Form의 data 값을 넣어주면 됩니다.
 
감사합니다.

 

Posted by 시리시안

댓글을 달아 주세요

  1. Favicon of https://dongkey2183.tistory.com BlogIcon Dongkey 2019.10.08 16:03 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다

2019. 3. 27. 11:50

안녕하세요. 게임개발자 놀이터 입니다.

유니티에 TMP가 정식으로 지원되면서 TMP에는 Sprite Importer 라는 기능이 있더군요!

이모티콘을 이걸로 표현 할 수 있지 않을까 방법을 좀 찾아봤습니다.

여러 사이트를 돌아다니면서 방법을 모아왔네요

나중에 동영상으로도 올릴계획 입니다.

<TMP Sprite Importer>


Sprite Data Source 에는 json 형식의 텍스트 에셋이 들어가야한다고 합니다.
(어떤 구조인지는 제 정보 검색 능력으로는 찾질 못했습니다... 그냥 JSON이여야 한다고...)

Improt Format 방식에는 noneTexturePacker가 있는데 
여기서 TexturePacker는 외부 프로그램을 말하고있네요!
TexturePacker  <-- 링크





프로그램을 다운 받고 설치 합니다



무료버전만으로도 충분히 사용 가능합니다!!


실행 화면입니다

이제 여기에 사용할 이미지들을 넣어줍니다.

저는 Unicode Emozi 모음을 사용했습니다.


현재 아웃풋 파일 방식이 Unity로 되어있는데 이를 Json(Array)형식으로 변경해줍니다.

(이때 크기를 2의 배수 단위로 강제 고정하면 더욱 안전하게 사용 하실 수 있습니다.)
(유니티에서 파일을 읽어올때 2의 배수로 읽어오기 때문에...)


저 JSON (Array)가 TMP에서 사용하는 그 Json 방식이랑 동일 하더군요!



저는 바탕화면에 폴더를 만들어서 Json 파일과 png파일이 출력되도록했습니다.



이제 상단 Publish sprite sheet 를 출력합시다.



제대로 잘 나왔네요! 게다가 TMP가 쓰는 방식 구조도 알 수 있었습니다!

이제 다시 유니티로 돌아갑시다.


먼저 2개의 파일을 유니티에 넣어줍니다


그후 Sprite Importer 을 열어서 Json파일과 Atlas를 넣어줍니다

그후 Create Sprite Asset을 누른 후 Save Sprite Asset을 눌러줍니다!

그럼 생성된 스프라이트 데이터를 확인 할 수 있습니다.


위 파일을 TMP EXTRA SETTINGS 에 Sprite Asset에 넣어줍니다


그럼 이제 이모티콘을 입력해봅시다!

유니코드 이모티콘이라 유니티에선 지원해주지 않아, 입력해도 에디터에선 표시되지 않지만


이렇게 입력한 ( 뒤에 이모티콘이 붙어있어요! 안보일뿐..) TMP에서는

이렇게 출력되게 됩니다!

이제 원하는 대로 전부 변경 할 수 있겠네요.

감사합니다~



+ 추가



<sprite=id> 태그로도 이모티콘을 출력 할 수 있습니다. 이쪽이 더 간편해 보이네요!




읽어주셔서 감사합니다!





Posted by 시리시안

댓글을 달아 주세요

2019. 3. 25. 15:42
안녕하세요. 게임개발자 놀이터입니다

에버노트에서 티스토리 글을 쓰는 방법에 대해 포스팅 해보려합니다!

원래 즐겨 쓰는 방법이 원노트라 원노트로 어떻게든 해보려고 했으나... 실패하고 에버노트로 넘어왔습니다..

이 포스팅도 에버노트로 작성했습니다.

먼저 티스토리 관리자 페이지에 접속합니다.

그후 좌측 메뉴 중 플러그인을 클릭합니다.



플러그인 목록에 에버노트를 검색합니다.



저는 이미 [사용중] 으로 되어있는데, 이건 무시하세요~

클릭해서 뜨는 창에서 계정을 연동해줍니다



[계정 다시 연결하기] 부분에 있습니다.

에버노트 아이디로 연결만 해주면 완성!

그후 에버노트로 넘어갑니다.

이제 글을 쓸때 태크로 '티스토리' 을 적어주기만 하면됩니다.



이제 다시 티스토리로 넘어갑니다.

글쓰기를 누르시면 우측 상단에 에버노트 버튼이 보입니다

\


클릭하시면 새창에 자동으로 티;스토리 태크가 붙은 모든 노트를 보여줍니다



클릭 하게되면 모든 내용이 글쓰기로 이동합니다

이미지를 하나하나 저장 하지 않아도 되서 너무 편하네요!

읽어주셔서 감사합니다.

Posted by 시리시안

댓글을 달아 주세요

2018. 7. 2. 10:35

안녕하세요. 게임개발자 놀이터입니다.


정말 오랜만에 포스팅하네요. 


이번에 포스팅할 내용은


팝콘에듀 체험단 이벤트로 당첨된 노터치 크라켄 체험 후기를 써보려고합니다.


아주 간단한 룰에 운과 블러핑! 으로 싸우는 게임이었어요


먼저 개봉 사진 부터 보시죠!



크라켄에 맞싸우며(?) 보물을 찾는 해적단의 모습이군요.

배에는 이미 보물이있고.. 크라켄이 눈을 뜬거 보니


해골병사팀이 승리한거 같습니다(?)



내용물이네요. 승점 토큰으로 사용되는 문어 토큰과, 선플레이어 마커


그리고 플레이어 직업을 알 수있는 4명의 모험가와 2명의 해골병사

어린아이도있는거같은데.. 노동법이..?



다음은 플레잉 카드입니다.


크라켄이 배를 침몰 직전까지 몰로가고있는 크라켄카드


보물이 가득한 보물상자


죽은 생선시체가있는 빈 상자가있네요


저 생선은 어떻게 들어와서 죽어있는걸까요?



프로텍터를 씌웠는데도 케이스에 딱 맞게 들어갑니다. 아주 조금..? 압박감이 느껴져요~!




그럼 이제 플레이 후기 입니다.



첫 플레이는 카페에서 4인플레이로 이루어졌습니다.


직업과 카드를 전부 분배한 상황이애요


4명 모두가 보물을 가지고있다고 하네요!

아무도 크라켄은 없고..!


보물은 4장인데.. 저희가 부른 보물의 합은 5장..!?

분명 해골병사가 숨어서 거짓말을 하고있네요



하지만, 성공적으로 보물을 하나 찾아내는 모험가 팀!


그 후..




서로가 서로를 믿을 수 없는 상황이 되어, 1라운드가 종료되었습니다. 


보물은 딱 하나 찾아냈네요.


이번에도 역시 보물 갯수가 넘쳐나네요..? 



하지만, 한쪽에서 보물이 2개가 나오면서 슬슬 해골 병사가 누군지 추측 되게 됩니다.



3라운드로 들어갑니다. 마지막 보물 1장만 더 찾으면 되는데요.


사진상 왼쪽에 있는 플레이어가 보물이 있다고 하고 다른 사람들은 보물을 전부 안갖고 있다고 하네요!


드디어 모험가 팀이 이기는 방향인건가!


당연히 왼쪽 플레이어의 카드를 뽑는 그 순간!



아니 크라켄이!! 크라켄이 깨어났습니다!! 


보물을 가지고있다던 사람이 크라켄을 들고있었네요!


그럼 보물은 어디로 간걸까요!?



해골병사가 2명이었네요!


다른 1개의 보물은 해골병사인 제가 숨긴것이었습니다..


이렇게 해골병사팀의 승리로 첫 플레이 게임이 끝이 났습니다.



다음은 동호회 모임 '보관함' 에서 놀러간 여름 엠티에서 플레이한 사진입니다.


6명이 가득차, 해골병사 2명, 모험가 4명으로 게임을 시작합니다.


보물을 말했으나.. 역시나.. 총 보물의 합이 7개 네요?


에라 모르겠다. 보물을 가졌다는 사람을 골라 봅니다.



아쉽게도.. 빈상자로 게임을 시작하네요. 하지만 확률 이었으니 어쩔수 없고!



그뒤로 선플레이어 주고받기를 통해 나머지 보물들을 찾아냅니다!


벌써 보물 2개나! 1라운드 마지막 선택의 결과는!?



세상에 보물 3개! 다들 모험가였어요!


1라운드의 벌써 보물 6개중 3개를 찾아 냈네요! 엄청난 성과입니다.



2라운드 진행중입니다. 


이번엔 이상하게도 보물 갯수가 부족하네요..? 


해골병사가 숨겨버렸습니다.



그래도 남은 보물들을 찾아내는 모험가팀! 



아쉽게도 2라운드에선 해골병사가 보물을 숨겨버려서, 1개밖에 못찾았네요. 그래도 벌써 4개!


앞으로 2개!! 과연 모험가 팀은 승리 할 것인가!



빠르게.. 지나갔네요..


3라운드엔 보물을 하나도 찾지 못했습니다.


해골병사들이 계속 보물을 숨기네요.. 이때 이미 해골병사가 누군지 1명을 밝혀졌습니다.



마지막 4라운드..! 


보물을 들고있다는 이미 밝혀진 해골병사..!


저말을 믿어야하는가..?


그리고 크라켄을 들고있다던 다른 플레이어!


어쩔수없이 카드를 뽑았으나..



크라켄이 일어나면서 해골병사의 승리가 되었습니다..!


남았던 모든 보물 2장을 진짜 해골병사가 들고있었네요






이렇게 2회 플레이를 진행해봤습니다.


블러핑과 운의 요소가 섞여들어간, 크라켄 게임!


아무리 사람을 잘 속이고 속여도.. 운이 없다면..? 혹은 운이 좋다면 승리 할 수있는 게임이었습니다.


옵션룰로 '선플레이어 주고받기 금지'도 있다고 들었는데, 옵션룰은 적용하는게 좋을꺼같습니다.


해골병사가 2명 확정인 6인플레이에선, 해골병사가 선턴을 먹는다면, 다른 해골병사의 커밍아웃을 요구 하면서 서로 주고받기만 하면 4라운드동안 보물을 전부 못찾을 확률이 높으니까요.


하지만 정말 간단한 룰에 즐기기엔 안성맞춤인 게임이었습니다



이상 노터치 크라켄 플레이 후기였습니다.




Posted by 시리시안

댓글을 달아 주세요

  1. 냥이 2020.09.13 17:13  댓글주소  수정/삭제  댓글쓰기

    혹시 인물카드 카드 프로텍터 사이즈가 어떻게 되나요? 노터치 크라켄을 자주하다보니까 손때가 뭍는 것 같아서요ㅎ 프로텍터가 있어야겠더라구요ㅎ

2017. 11. 1. 11:40

안녕하세요. 게임 개발자 놀이터입니다.


이번 포스팅은 애플 게임 센터 ( Apple GameCentor ) 를 유니티를 이용해 연동하는 방법을 적어보려고합니다.


감사합니다.



SDK 다운로드 경로 

https://github.com/playgameservices/play-games-plugin-for-unity


구글 플레이 서비스 SDK를 같이 사용합니다. IOS의 경우 추가적인 설정을 해줘야합니다.

SDK 설정에 적어뒀으니 꼭 확인하세요!


SDK 설치 및 설정 방법


0. IOS상태에서 패키지를 추가하거나, 패키지를 추가한 상태에서 IOS로 변경할 경우 Cocoapods 설치가 진행됩니다.

아래와 같이 팝업창이 뜰때까지 기다려줍니다.


 


1. 게임센터 서비스를 이용하기 위해선 아래 링크로 들어갑니다.

https://itunesconnect.apple.com/

 




2. 여러 버튼중 ‘나의 앱’을 눌러서 들어 간후, 좌 상단에 + 버튼을 눌러 신규 앱을 만들어 줍니다.

 




3. 아래와 같이 알맞는 정보를 적어줍니다.


 



4. 상단 메뉴 ‘앱 내 추가 기능’ 에서 ‘Game Centor’ 로 들어갑니다.



 

5. 상단은 순위효과(리더보드) 하단은 목표 달성 (업적) 입니다. 

 



6. 순위표에서 + 버튼을 눌러 아래와 같은 창을 띄웁니다.



 

7. 우리가 만들껀 개별 순위표 입니다, 개별 순위표를 선택해 아래와 같이 입력해줍니다.

 

여기서 순위표 ID는 구글 콘솔에서 가져오셔야 합니다.


8. 입력 후 로컬라이징을 위해 아래 언어 추가를 누른 후 Korean을 선택합니다.

 


9. 언어 추가를 누른뒤 아래와 같이 입력해줍니다. 


 


10. 아래와 같이 추가 되었다면 성공!

 



11. 이번엔 목표 달성을 추가해봅시다.


 

리더보드와 다를껀 없습니다. ID는 구글콘솔과 동일하게 맞춰줘야 합니다.


12. 사진이 꼭 필요합니다! 사이즈에 맞춰서 추가해줍시다.

 



13. 이제 유니티에서 iOS 셋업을 해줍니다. 

 



14. ClientID는 구글 콘솔에서 받아온내용으로 적고, Object-C Resources 는 구글 콘솔에서 리소스 받기 – Object-C 로 받아온 내용으로 적어둡니다.

 


15. 이제 IOS 세팅만 남았습니다.


GooglePlay는 더이상 IOS를 지원하지 않는다고합니다. 그런데도 GooglePlaySDK를 사용하여 iOS 기능을 사용하는 점은, 구글 콘솔을 통하여 업적과 리더보드등 한개로 통일하기 위함입니다.
하지만, 더이상 지원하지 않는 기능의 코드들이 iOS빌드할때 같이 나나게 됩니다. 따라서 NO_GPGS 라는 Define을 추가해줘야 합니다.
PlayerSetting – iOS – Other Settings – Scripting Define Symebol 에 NO_GPGS 를 추가해줍니다.




API
주로 사용 해야할 API 입니다.



로그인
애플 게임 센터 서비스에 로그인합니다.
Social.localUser.Authenticate((bool success) => {
//handle success or failure
});

업적 달성
업적은 0~100까지 달성도로 나타냅니다.
// unlock achievement (achievement ID "Cfjewijawiu_QA")
Social.ReportProgress("Cfjewijawiu_QA", 100.0f, (bool success) => {
//handle success or failure
});

리더보드에 점수 게시
리더보드에 점수를 게시합니다.
//post score 12345 to leaderboard ID "Cfji293fjsie_QA")
social.ReportScore(12345, "Cfji293fjsie_QA", (bool success) =>{
//handle success or failure
});

업적 UI 보여주기
모든 업적이 보이는 UI창을 띄웁니다.
//show achievements UI
Social.ShowAchievementsUI();

리더보드 UI 보여주기
리더보드 UI창을 띄웁니다.
        // show leaderboard UI
Social.ShowLeaderboardUI();




감사합니다.






Posted by 시리시안

댓글을 달아 주세요

2017. 10. 30. 15:23

안녕하세요. 게임 개발자 놀이터입니다.


이번 포스팅은 구글 플레이 게임 서비스(Google Play Game Services)(이하 GPG)를 유니티를 이용해 연동하는 방법을 적어보려고합니다.


감사합니다.




구글 플레이 서비스 ( Google Play Services ) Unity 연동


구글 플레이 서비스 for Unity 는 아래와 같은 기능을 제공합니다.

  • 플러그인이 Google Play Games API 중 지원하는 기능
  • 로그인
  • 업적 잠금 해제, 발견, 증가
  • 리더보드에 점수 등록
  • 클라우드 세이브 읽기/쓰기
  • 내장 업적/리더보드 UI
  • 이벤트 및 퀘스트
  • 턴제 멀티플레이
  • 실시간 멀티플레이


1. SDK 다운로드

SDK 다운로드 : https://github.com/playgameservices/play-games-plugin-for-unity


Current-build 안에 있는 Unity Packages 를 프로젝트에 추가 합니다.




다음과 같이 프로젝트에 추가 되었다면 성공입니다!



 

2. 어플리케이션 등록 & 안드로이드 셋업


구글 플레이 서비스를 이용하려면 구글 개발자 등록이 되어있어야합니다.

그럼 구글 개발자 등록이 되어있다고 가정하에 아래 개발자 사이트를 들어갑니다.


https://play.google.com/apps/publish/


오른쪽 애플리케이션 만들기를 선택해, 애플리케이션을 만들어줍니다

(유니티에서 기본으로 빌드한 APK를 넣어주면 됩니다. )



설정을 끝낸후, 게임 서비스 탭으로 이동하여, 마찬가지로 새 게임 추가를 눌러서 추가해줍니다.



추가가 완료되었다면, 클릭해서 들어가 봅시다.




연결된 앱을 클릭해서 들어가줍니다!




패키지 이름을 클릭해 만든 게임과 연동시키고, 턴방식 멀티플레이나 실시간 멀티 플레이라면 알맞게 사용을 체크해줍니다!



그리고 돌아와 오른쪽 메뉴에서 업적이나 리더보드등 여러가지 추가하고 싶은것들을 알맞게 추가해줍니다~




그후 밑에 보이는 리소스 받기 버튼을 눌러서 나오는 XML 내용을 복사해둡시다!




자, 이제 다시 유니티로 돌아갑시다.


Window - Google Play Games - Setup - Android setup... 을 눌러줍시다.




그럼 아래와 같은 창이 뜰겁니다. 먼저 가운데 Resources Definition 에 아까 복사한 XML리소스를 붙어넣어 줍니다.

그리고 Constants class name은 이걸로 생성될 클래스의 위치를 잡아줍니다. 저같은 경우 GPGTest.Test 라고 해줬었습니다.


그후 중요한건 맨밑에 ClinetID인데, 이건 다시 구글 개발자 콘솔로 돌아갑니다.




게임 서비스 - 연결된 앱  으로 들어가 연결한 앱을 누르면 맨밑에 정보가 나옵니다.




이중 OAuth2 클라이언트 ID를 복사해서 위 Client ID에 붙어 넣어주고 Setup을 누릅니다.


그럼 확인창 2개가 뜰텐데, 그 중



와 같이 뜬다면 완벽합니다!



3. 구글 로그인 및 업적, 리더보드 올리기




초기화

구글 플레이게임 서비스를 초기화합니다.

//Activate the Google Play gaems platform

PlayGamesPlatform.Activate();


로그인

구글 서비스에 로그인합니다.

Social.localUser.Authenticate((bool success) => {

//handle success or failure

});


업적 달성

업적은 0~100까지 달성도로 나타냅니다.

// unlock achievement (achievement ID "Cfjewijawiu_QA")

Social.ReportProgress("Cfjewijawiu_QA", 100.0f, (bool success) => {

//handle success or failure

});


리더보드에 점수 게시

리더보드에 점수를 게시합니다.

//post score 12345 to leaderboard ID "Cfji293fjsie_QA")

social.ReportScore(12345, "Cfji293fjsie_QA", (bool success) =>{

//handle success or failure

});


업적 UI 보여주기

모든 업적이 보이는 UI창을 띄웁니다.

//show achievements UI

Social.ShowAchievementsUI();


리더보드 UI 보여주기

리더보드 UI창을 띄웁니다.

        // show leaderboard UI

Social.ShowLeaderboardUI();


게임 상태를 클라우드에 저장하기

클라우드의 게임을 저장합니다.

         public class MyClass : OnStateLoadedListener {

void SaveState() {

// serialize your game state to a byte array:

byte[] mySaveState = ...;

int slot = 0; // slot number to use

((PlayGamesPlatform) Social.Active).UpdateState(slot,

mySaveState, this);

}

public void OnStateSaved(bool success, int slot) {

// handle success or failure

}

}


게임 상태를 클라우드로부터 불러오기

클라우드에서 게임을 불러옵니다.

        public class MyClass : OnStateLoadedListener {

void LoadState() {

int slot = 0; // slot number to use

((PlayGamesPlatform) Social.Active).LoadState(slot, this);

}

public void OnStateLoaded(bool success, int slot, byte[] data) {

if(success) {

//do something with data[]

} else {

//handle failure

}

}

}


클라우드 충돌 해결

2개 이상의 기기에서 클라우드를 나눠쓴다면 충돌이 날 수 있습니다. 

public class MyClass : OnStateLoadedListener {

public byte[] OnStateConflict(int slot, byte[] local, byte[] server){

//resolve conflict and return a byte[] representing the

//resolved state.

}

}



4. 실시간 & 턴기반 멀티플레이 구현하기

실시간 멀티 플레이 – 빠른 게임 만들기

특정수의 자동 상대와 빠른 매칭을 시도합니다.

const int MinOpponents = 1 MaxOpponents = 3;

const int GameVariant = 0;

PlayGamesPlatform.Instance.RealTime.CreateQuickGame (MinOpponents, MaxOpponents,

GameVariant, listener);


실시간 멀티 플레이 – 초대 화면

원하는 친구를 선택할수있는 초대화면을 표시합니다.

const int MinOpponents = 1 MaxOpponents = 3;

const int GameVariant = 0;

PlayGamesPlatform.Instance.RealTime.CreateWithInvitationScreen (MinOpponents, MaxOpponents,

GameVariant, listener);


실시간 멀티 플레이 – 초대장 표시하기

사용자가 받은 초대를 표시합니다.

PlayGamesPlatform.Instance.RealTime.AcceptFromInbox (listener);


실시간 멀티 플레이 – 초대 엑세스

초대 수락후 초대장에 엑세스합니다

PlayGamesPlatform.Instance.RealTime.GetInvitation ();


실시간 멀티 플레이 – 초대 수락

초대를 수락합니다.

Invitation invitation = ....;  // (obtained via delegate)

    PlayGamesPlatform.Instance.RealTime.AcceptInvitation(invitationId, invitation.InvitationId);


실시간 멀티 플레이 – 모든 초대장 표시하기

받은 모든 초대장을 표시합니다.

PlayGamesPlatform.Instance.RealTime.GetAllInvitations(

        (invites) =>

        {

            Debug.Log("Got " + invites.Length + " invites");

            string logMessage = "";

            foreach(Invitation invite in invites)

            {

                logMessage += " " + invite.InvitationId + " (" +

                    invite.InvitationType + ") from " +

                    invite.Inviter + "\n";

                if (mFirstInvite == null) {

                    mFirstInvite = invite;

                }

            }

            Debug.Log(logMessage);

    });


실시간 멀티 플레이 – 연결 대기

연결 상황에 따라 대기실을 표시해줍니다.

private bool showingWaitingRoom = false;

    public void OnRoomSetupProgress(float progress) {

        // show the default waiting room.

        if (!showingWaitingRoom) {

            showingWaitingRoom = true;

            PlayGamesPlatform.Instance.RealTime.ShowWaitingRoomUI();

        }

    }


실시간 멀티 플레이 – 매칭 완료

매칭이 완료되었을때 불리는 함수입니다.

public void OnRoomConnected(bool success) {

        if (success) {

            // Successfully connected to room!

            // ...start playing game...

        } else {

            // Error!

            // ...show error message to user...

        }

    }



실시간 멀티 플레이 – 참가자 인덱스

멀티에 참가한 플레이어들은 index로 구분됩니다.

Participant myself = PlayGamesPlatform.Instance.RealTime.GetSelf();

    Debug.Log("My participant ID is " + myself.ParticipantId);



실시간 멀티 플레이 – 참가자 목록

다른 참가자들을 인덱스로 받아옵니다.

List<Participant> participants = PlayGamesPlatform.Instance.RealTime.GetConnectedParticipants();



실시간 멀티 플레이 – 메세지 보내기

다른 모든 참가자들에게 메세지를 보낼수있습니다.

Reliable은 신뢰성의 여부를 따집니다.

byte [] message = ....; // 메시지를 작성하십시오. 

    bool  reliable = true ;

    PlayGamesPlatform.Instance.RealTime.SendMessageToAll (reliable, message);



실시간 멀티 플레이 – 메세지 받기

메세지가 도착했을때 불리는 함수입니다.

public void OnRealTimeMessageReceived(bool isReliable, string senderId, byte[] data) {

        // handle message! (e.g. update player's avatar)

    }



실시간 멀티 플레이 – 연결 이벤트 처리

유저가 게임을 나갔을때

public  void  OnLeftRoom () {

         // 오류 메시지를 표시하고 메뉴 화면으로 돌아갑니다.

        

        // (PlayGamesPlatform.Instance.RealTime.LeaveRoom ()을 여기에서 호출하지 마십시오.) 

        // 이미 방을 나왔습니다 !) 

    }


다른 유저가 방에 들어오거나 나갔을때

public  void  OnPeersConnected ( string [] participantIds ) {

         // 적절하게 반응합니다 (예 : 새 아바타를 게임에 추가).

    }

    

    public  void  OnPeersDisconnected ( string [] participantIds ) {

         // 적절하게 반응 (예 : 게임에서 아바타 제거) 

    }


실시간 멀티 플레이 – 방 나가기

방에서 나옵니다.

PlayGamesPlatform.Instance.RealTime.LeaveRoom ();




턴 멀티 플레이 – 빠른 게임

퀵 매치를 시작합니다.

PlayGamesPlatform.Instance.TurnBased.CreateQuickMatch(MinOpponents, MaxOpponents,

        Variant, OnMatchStarted);


    // Callback:

    void OnMatchStarted(bool success, TurnBasedMatch match) {

        if (success) {

            // go to the game screen and play!

        } else {

            // show error message

        }

    }


턴 멀티 플레이 – 초대 화면

초대가 가능한 화면으로 만듭니다.

PlayGamesPlatform.Instance.TurnBased.CreateWithInvitationScreen(MinOpponents, MaxOpponents,

        Variant, OnMatchStarted);


턴 멀티 플레이 – 초대보기

받은 초대를 봅니다.

PlayGamesPlatform.Instance.TurnBased.AcceptFromInbox(OnMatchStarted);


턴 멀티 플레이 – 초대 수락

받은 초대를 수락합니다.

PlayGamesPlatform.Instance.TurnBased.AcceptFromInbox(OnMatchStarted);


턴 멀티 플레이 – 모든 초대장 보기

받은 모든 초대장을 표시합니다.

PlayGamesPlatform.Instance.TurnBased.GetAllInvitations(

        (invites) =>

        {

            Debug.Log("Got " + invites.Length + " invites");

            string logMessage = "";

            foreach(Invitation invite in invites)

            {

                logMessage += " " + invite.InvitationId + " (" +

                    invite.InvitationType + ") from " +

                    invite.Inviter + "\n";

                if (mFirstInvite == null) {

                    mFirstInvite = invite;

                }

            }

            Debug.Log(logMessage);

    });


턴 멀티 플레이 – 매치 완료

매치가 완료되었다는 콜백을 받습니다.

void OnMatchStarted(bool success, TurnBasedMatch match) {

        if (success) {

            // get the match data

            byte[] myData = match.Data;

            

            // I can only make a move if the match is active and it's my turn!

            bool canPlay = (match.Status == TurnBasedMatch.MatchStatus.Active &&

                match.TurnStatus == TurnBasedMatch.MatchTurnStatus.MyTurn);

            

            // Deserialize game state from myData into scene and

            // go to gameplay screen. If canPlay == true, let user play a move; 

            // if not, they can only see the current state of the game but can't play.

        } else {

            // show error message, return to main menu

        }

    }


턴 멀티 플레이 – 내 차례 알림

내 차례를 알려주는 콜백을 받습니다.

TurnBasedMatch match = ....; // received in OnMatchStarted

    

    // your representation of the new state of the game after the player

    // has taken their turn:

    byte[] myData = .....;

    

    // this indicates whose turn is next (a participant ID)

    string whoIsNext = .....;

    

    PlayGamesPlatform.Instance.TurnBased.TakeTurn(match.MatchId, myData, whoIsNext, (bool success) => {

        if (success) {

            // turn successfully submitted!

        } else {

            // show error

        }

    });


턴 멀티 플레이 – 턴 넘기기

자동으로 다음 플레이어에게 넘기거나, 특정 플레이어에게 턴을 넘깁니다.

string DecideWhoIsNext(TurnBasedMatch match) {

        if (match.AvailableAutomatchSlots > 0) {

            // hand over to an automatch player

            return null;

        } else {

            // pick a player among match.Participants,

            // according to the game's logic

        }

    }


턴 멀티 플레이 – 경기 끝

경기가 끝낫을떄 받는 함수입니다.

TurnBasedMatch match = .....;  // our current match

    byte[] finalData = .....; // match data representing the final state of the match

    

    // define the match's outcome

    MatchOutcome outcome = new MatchOutcome();

    foreach (Participant p in match.Participants) {

        // decide if participant p has won, lost or tied, and

        // their ranking (1st, 2nd, 3rd, ...):

        MatchOutcome.ParticipantResult result = .....;

        int placement = ......;

        

        outcome.SetParticipantResult(p.ParticipantId, result, placement);

    }

   

    // finish the match

    PlayGamesPlatform.Instance.TurnBased.Finish(match.MatchId, finalData, outcome, (bool success) => {

        if (success) {

            // sent successfully

        } else {

            // an error occurred

        }

    });


턴 멀티 플레이 – 게임 나가기

필요하다면 아래 함수로 게임을 나갈수 있습니다.

PlayGamesPlatform.Instance.TurnBased.Leave(match.MatchId, (bool success) => {

        if (success) {

            // successfully left

        } else {

            // error leaving match

    });




감사합니다!!

Posted by 시리시안

댓글을 달아 주세요