유저정보 저장 로드
상점 기능을 구현하기 전에 뒤끝을 이용하여 유저 정보를 저장할 수 있도록 만들어야 한다.
다른 baas도 있지만 굳이 뒤끝을 고른 이유는 한글로 개발문서가 잘 정리되어 있고 기능도 나날히 발전중이다.
그리고 인앱결제보다 광고 비중이 더 높은 게임들은 뒤끝을 이용하는것이 값싸다.
뒤끝에서 프로젝트를 하나 생성해주자

그 다음 유니티에 dotnet4 버전 뒤끝 sdk를 임포트 해준다.

클라 id 시그니처 id 등록을 해줌으로서 뒤끝과 연동을 해준다.

그리고 뒤끝에 로그인을 해주기위한 씬을 따로 만들거다.
기존에 있던 씬을 로비로 명칭해주고 로그인 씬을 하나 만들어준다.

로그인 씬 ui는 대충 이렇게 만들어준다.

시작할 때 뒤끝을 초기화 시켜줄 코드를 작성해보자
using BackEnd; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class BackendInitialized : MonoBehaviour { void Awake() { Backend.Initialize(HandleBackendCallback); } void HandleBackendCallback() { if (Backend.IsInitialized) { Debug.Log("서버시간"); // 서버시간 획득 BackendReturnObject servertime = Backend.Utils.GetServerTime(); string time = servertime.GetReturnValuetoJSON()["utcTime"].ToString(); DateTime parsedDate = DateTime.Parse(time); Debug.Log(parsedDate.Hour + "시" + parsedDate.Minute + "분"); } // 실패 else { Debug.LogError("Failed to initialize the backend"); } } } |
초기화가 완료되면 서버의 시간을 찍어주도록 했다.
본 프로젝트는 PC버전으로 만들기 때문에 따로 해쉬키를 받아올 필요는 없다.
로그인 스크립트를 아래와 같이 만들자
using BackEnd; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class BackendAuth : MonoBehaviour { public InputField id; public InputField password; public void CustomSignUp() { BackendReturnObject bro = Backend.BMember.CustomSignUp(id.text, password.text); if (bro.IsSuccess()) { Debug.Log("회원가입 완료"); CustomLogin(); Nickname(); SceneMove(); } else { switch (bro.GetStatusCode()) { case "409": Debug.Log("중복된 customId 가 존재하는 경우"); CustomLogin(); SceneMove(); break; case "403": Debug.Log("출시설정이 테스트 인데 AU가 10을 초과한 경우"); break; } } } void CustomLogin() { BackendReturnObject bro = Backend.BMember.CustomLogin(id.text, password.text); if (bro.IsSuccess()) { Debug.Log("로그인 완료"); } else { switch (bro.GetStatusCode()) { case "401": Debug.Log("존재하지 않는 아이디의 경우 or 비밀번호가 틀린 경우"); break; case "403": Debug.Log("차단당한 유저인 경우 or 출시설정이 테스트 인데 AU가 10을 초과한 경우"); break; } } } void Nickname() { Backend.BMember.CreateNickname(id.text); } void SceneMove() { SceneManager.LoadScene("로비"); } } |
먼저 회원가입을하고 해당 유저가 이미 회원가입되어 있는 유저라면 바로 로그인
아니라면 회원가입 후 로그인을 시켜주도록 했다.
로그인이 완료되면 로비씬으로 넘어간다.
콘솔창에서 결과를 확인하고


뒤끝에서도 잘 가입이 되어진 모습을 확인 할 수 있었다.
게임매니저라는 빈 오브젝트에 게임매니저 스크립트를 하나 붙여준다.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { void Start() { DontDestroyOnLoad(this.gameObject); } } |
다른 씬으로 이동해도 오브젝트가 파괴되지 않도록 했다.
뒤끝에 정보를 저장하기 위한 스크립트를 만들어서 게임매니저 오브젝트에 붙여주자
using System.Collections; using System.Collections.Generic; using UnityEngine; using BackEnd; using LitJson; public class BackendGameInfo : MonoBehaviour { public static BackendGameInfo instance; private void Awake() { instance = this; } [HideInInspector] public List<string> serverDataList = new List<string>(); // 서버 테이블에 정보 넣기 [System.Obsolete] public void Insert(string table, Param param, System.Action sucess = null) { BackendAsyncClass.BackendAsync(Backend.GameInfo.Insert, table, param, (callback) => { string stateCode = callback.GetStatusCode(); switch (stateCode) { case "404": // 존재하지 않는 tableName인 경우 Debug.Log("존재하지 않는 tableName인 경우 "); break; case "412": // 비활성화 된 tableName인 경우 Debug.Log("비활성화 된 tableName인 경우 "); break; case "413": // 하나의 row( column들의 집합 )이 400KB를 넘는 경우 Debug.Log("하나의 row( column들의 집합 )이 400KB를 넘는 경우 "); break; default: break; } sucess(); }); } // 개인 프라이빗 테이블 정보 가져오기 [System.Obsolete] public void GetPrivateContents(string table, string key, System.Action sucess = null, System.Action fail=null) { serverDataList.Clear(); BackendAsyncClass.BackendAsync(Backend.GameInfo.GetPrivateContents, table, (callback) => {
string stateCode = callback.GetStatusCode(); switch (stateCode) { case "200": // 성공 break; case "404": // 존재하지 않는 tableName인 경우 Debug.Log("존재하지 않는 tableName인 경우 "); break; case "400": // private table 아닌 tableName을 입력한 경우 또는 limit이 100이상인 경우 Debug.Log("private table 아닌 tableName을 입력한 경우 또는 limit이 100이상인 경우"); break; case "412": // 비활성화 된 tableName인 경우 Debug.Log("비활성화 된 tableName인 경우 "); break; default: break; } if (callback.GetReturnValuetoJSON()[0].Count == 0) // 테이블에 해당 유저의 정보가 아무것도 없는 경우 { Param param = new Param(); param.Add("N", 0); Insert(table, param, ()=> { GetPrivateContents(table, key, sucess, fail); }); } else { JsonData jsonData = callback.GetReturnValuetoJSON()[0][0]; if (jsonData.Keys.Contains(key)) { if (jsonData[key].Keys.Contains("L")) // 리스트형 데이터인지 아닌지 { JsonData keyData = jsonData[key][0]; for (int i = 0; i < keyData.Count; i++) { serverDataList.Add(keyData[i][0].ToString()); } } else { serverDataList.Add(jsonData[key][0].ToString()); } if (sucess != null) { sucess(); } } else { if (fail != null) fail(); } } }); } // 개인 테이블 정보 수정 [System.Obsolete] public void PrivateTableUpdate(string table, Param param, System.Action sucess = null) { GetPrivateContents(table, "inDate", () => { BackendAsyncClass.BackendAsync(Backend.GameInfo.Update, table, serverDataList[0], param, (callback) => { string stateCode = callback.GetStatusCode(); switch (stateCode) { case "405": // param에 partition, gamer_id, inDate, updatedAt 네가지 필드가 있는 경우 Debug.Log("param에 partition, gamer_id, inDate, updatedAt 네가지 필드가 있는 경우"); break; case "403": // 퍼블릭테이블의 타인정보를 수정하고자 하였을 경우 Debug.Log("퍼블릭테이블의 타인정보를 수정하고자 하였을 경우"); break; case "404": // 존재하지 않는 tableName인 경우 Debug.Log("존재하지 않는 tableName인 경우"); break; case "412": // 비활성화 된 tableName인 경우 Debug.Log("비활성화 된 tableName인 경우 "); break; case "413": // 하나의 row( column들의 집합 )이 400KB를 넘는 경우 Debug.Log("하나의 row( column들의 집합 )이 400KB를 넘는 경우"); break; default: break; } if (sucess != null) sucess(); }); }); } } |
뒤끝 개발문서를 보고 데이터를 저장하고 불러오기 쉽게 만들어놓았다.
일단 개인 데이터만 불러올 수 있도록 만들었는데 차후에 공용데이터도 불러올 수 있도록 수정을 해야할 것이다.
dlfwlcn