본문 바로가기
▶ SCP전쟁 개발일지

#012 유니티 구글 플레이 로그인 구현 (GPGS 로그인, 업적, 리더보드, 이벤트)

by 곰스타일 2024. 4. 12.
728x90
반응형
SMALL

1. 개발자 콘솔 - 대시보드 - 앱클릭 - 앱설정 - 앱 엑세스 권한 - 사용으로 설정

 

 

2. 개발자 콘솔 - play 게임즈 서비스 - 설정 및 관리 - 설정 - 속성 수정 - 저장된 게임 '사용'으로 체크

 

3. 구글 클라우드 콘솔 - 라이브러리 - sdk 검색 - Google Workspace Marketplace SDK 클릭 후 사용 클릭

3. 구글 클라우드 콘솔 - api 및 서비스 - 사용자 인증 정보에 반드시 OAuth 2.0 클라이언트 ID 3개 있어야함

(안드로이드 2개와 클라이언트 id 1개)

 

여기서 안드로이드 아이디 2개는 각각 테스트 앱과 실행하는 앱 서명이 들어간 클라이언트이고,

웹 애플리케이션은 서버 id임

 

4.  3번에서 웹 애플리케이션 클라이언트ID 복사

유니티 - Window - Google Play Games - Setup - Android setup - 맨아래 Client ID 부분에 붙여넣기

 

 

5. 개발자 콘솔 - play 게임즈 서비스 - 설정 및 관리 - 설정 - 사용자 인증 정보 - 리소스 보기 - Android(XML) 부분 복사

유니티 - Window - Google Play Games - Setup - Android setup - 가운데 가장 큰 창에 붙여넣기 - Setup 버튼 클릭

 

 

6. 유니티 - 에셋 - 익스터널 디펜던시 - 안드로이드 리졸브 - 폴스 리졸브

(안드로이드 파일 업그레이드 하는 부분)

 

7. 유니티 - 에셋 - 익스터널 디펜던시 - 버전 핸들러 - 셋팅 - Verbose logging 부분 비활성화

(체크 해제하면 불필요한 log안뜸)

 

8. 아래와 같이 스크립트 2개 생성 ( GPGSBinder, Test )

Test 스크립트만 오브젝트에 컴포넌트한 후 핸드폰 연결하여 빌드앤런 실행해보기

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using GooglePlayGames.BasicApi.SavedGame;
using GooglePlayGames.BasicApi.Events;


public class GPGSBinder
{
    static GPGSBinder inst = new GPGSBinder();
    public static GPGSBinder Inst => inst;



    ISavedGameClient SavedGame => 
        PlayGamesPlatform.Instance.SavedGame;

    IEventsClient Events =>
        PlayGamesPlatform.Instance.Events;



    void Init()
    {
        var config = new PlayGamesClientConfiguration.Builder().EnableSavedGames().Build();
        PlayGamesPlatform.InitializeInstance(config);
        PlayGamesPlatform.DebugLogEnabled = true;
        PlayGamesPlatform.Activate();
    }


    public void Login(Action<bool, UnityEngine.SocialPlatforms.ILocalUser> onLoginSuccess = null)
    {
        Init();
        PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptAlways, (success) =>
        {
            onLoginSuccess?.Invoke(success == SignInStatus.Success, Social.localUser);
        });
    }

    public void Logout()
    {
        PlayGamesPlatform.Instance.SignOut();
    }


    public void SaveCloud(string fileName, string saveData, Action<bool> onCloudSaved = null)
    {
        SavedGame.OpenWithAutomaticConflictResolution(fileName, DataSource.ReadCacheOrNetwork,
            ConflictResolutionStrategy.UseLastKnownGood, (status, game) =>
            {
                if (status == SavedGameRequestStatus.Success)
                {
                    var update = new SavedGameMetadataUpdate.Builder().Build();
                    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(saveData);
                    SavedGame.CommitUpdate(game, update, bytes, (status2, game2) =>
                    {
                        onCloudSaved?.Invoke(status2 == SavedGameRequestStatus.Success);
                    });
                }
            });
    }

    public void LoadCloud(string fileName, Action<bool, string> onCloudLoaded = null)
    {
        SavedGame.OpenWithAutomaticConflictResolution(fileName, DataSource.ReadCacheOrNetwork, 
            ConflictResolutionStrategy.UseLastKnownGood, (status, game) => 
            {
                if (status == SavedGameRequestStatus.Success)
                {
                    SavedGame.ReadBinaryData(game, (status2, loadedData) =>
                    {
                        if (status2 == SavedGameRequestStatus.Success)
                        {
                            string data = System.Text.Encoding.UTF8.GetString(loadedData);
                            onCloudLoaded?.Invoke(true, data);
                        }
                        else
                            onCloudLoaded?.Invoke(false, null);
                    });
                }
            });
    }

    public void DeleteCloud(string fileName, Action<bool> onCloudDeleted = null)
    {
        SavedGame.OpenWithAutomaticConflictResolution(fileName,
            DataSource.ReadCacheOrNetwork, ConflictResolutionStrategy.UseLongestPlaytime, (status, game) =>
            {
                if (status == SavedGameRequestStatus.Success)
                {
                    SavedGame.Delete(game);
                    onCloudDeleted?.Invoke(true);
                }
                else 
                    onCloudDeleted?.Invoke(false);
            });
    }


    public void ShowAchievementUI() => 
        Social.ShowAchievementsUI();

    public void UnlockAchievement(string gpgsId, Action<bool> onUnlocked = null) => 
        Social.ReportProgress(gpgsId, 100, success => onUnlocked?.Invoke(success));

    public void IncrementAchievement(string gpgsId, int steps, Action<bool> onUnlocked = null) =>
        PlayGamesPlatform.Instance.IncrementAchievement(gpgsId, steps, success => onUnlocked?.Invoke(success));


    public void ShowAllLeaderboardUI() =>
        Social.ShowLeaderboardUI();

    public void ShowTargetLeaderboardUI(string gpgsId) => 
        ((PlayGamesPlatform)Social.Active).ShowLeaderboardUI(gpgsId);

    public void ReportLeaderboard(string gpgsId, long score, Action<bool> onReported = null) =>
        Social.ReportScore(score, gpgsId, success => onReported?.Invoke(success));

    public void LoadAllLeaderboardArray(string gpgsId, Action<UnityEngine.SocialPlatforms.IScore[]> onloaded = null) => 
        Social.LoadScores(gpgsId, onloaded);

    public void LoadCustomLeaderboardArray(string gpgsId, int rowCount, LeaderboardStart leaderboardStart, 
        LeaderboardTimeSpan leaderboardTimeSpan, Action<bool, LeaderboardScoreData> onloaded = null)
    {
        PlayGamesPlatform.Instance.LoadScores(gpgsId, leaderboardStart, rowCount, LeaderboardCollection.Public, leaderboardTimeSpan, data =>
        {
            onloaded?.Invoke(data.Status == ResponseStatus.Success, data);
        });
    }


    public void IncrementEvent(string gpgsId, uint steps) 
    {
        Events.IncrementEvent(gpgsId, steps);
    }

    public void LoadEvent(string gpgsId, Action<bool, IEvent> onEventLoaded = null)
    {
        Events.FetchEvent(DataSource.ReadCacheOrNetwork, gpgsId, (status, iEvent) =>
        {
            onEventLoaded?.Invoke(status == ResponseStatus.Success, iEvent);
        });
    }

    public void LoadAllEvent(Action<bool, List<IEvent>> onEventsLoaded = null)
    {
        Events.FetchAllEvents(DataSource.ReadCacheOrNetwork, (status, events) =>
        {
            onEventsLoaded?.Invoke(status == ResponseStatus.Success, events);
        });
    }

}

 

 

 

 


 

 

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

public class Test : MonoBehaviour
{
    public Text LogText;
    string log;
    string logText;

    public void ButtonClickLogin()
    {
        GPGSBinder.Inst.Login((success, localUser) =>
            log = $"{success}, {localUser.userName}, {localUser.id}, {localUser.state}, {localUser.underage}");
        Debug.Log(log);
        
        GPGSBinder.Inst.Login((success, localUser) =>
            logText = $"User Name: {localUser.userName},\n User ID: {localUser.id},\n User State: {localUser.state},\n User Underage {localUser.underage}");
        LogText.text = logText;
        
    }

    public void ButtonClickLogOut()
    {
        GPGSBinder.Inst.Logout();
        LogText.text = "Logout complete.";
    }
    
    /*void OnGUI()
    {
        GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * 2);//2배 정도 크기 키움


        if (GUILayout.Button("ClearLog")) //ClearLog 버튼 클릭 시
            log = ""; //로그를 깨끗하게 지우고

        //로그인
        if (GUILayout.Button("Login"))
            GPGSBinder.Inst.Login((success, localUser) =>
            log = $"{success}, {localUser.userName}, {localUser.id}, {localUser.state}, {localUser.underage}");
        //로그인 버튼 클릭 시 로그인 성공 여부와 로컬유저 의 여러가지 변수들을 받음
        
        if (GUILayout.Button("Logout"))
            GPGSBinder.Inst.Logout();

        if (GUILayout.Button("SaveCloud"))
            GPGSBinder.Inst.SaveCloud("mysave", "want data", success => log = $"{success}");

        if (GUILayout.Button("LoadCloud"))
            GPGSBinder.Inst.LoadCloud("mysave", (success, data) => log = $"{success}, {data}");

        if (GUILayout.Button("DeleteCloud"))
            GPGSBinder.Inst.DeleteCloud("mysave", success => log = $"{success}");

        if (GUILayout.Button("ShowAchievementUI"))
            GPGSBinder.Inst.ShowAchievementUI();

        
        //업적
        if (GUILayout.Button("UnlockAchievement_one"))
            GPGSBinder.Inst.UnlockAchievement(GPGSIds.achievement_one, success => log = $"{success}");

        if (GUILayout.Button("UnlockAchievement_two"))
            GPGSBinder.Inst.UnlockAchievement(GPGSIds.achievement_two, success => log = $"{success}");

        // 1개씩 증가하겠다는 의미(단계별 업적)
        if (GUILayout.Button("IncrementAchievement_three"))
            GPGSBinder.Inst.IncrementAchievement(GPGSIds.achievement_three, 1, success => log = $"{success}");
        
        //모든 리더보드 UI를 띄움
        if (GUILayout.Button("ShowAllLeaderboardUI"))
            GPGSBinder.Inst.ShowAllLeaderboardUI();

        //원하는 리더보드ui만 띄움
        if (GUILayout.Button("ShowTargetLeaderboardUI_num"))
            GPGSBinder.Inst.ShowTargetLeaderboardUI(GPGSIds.leaderboard_num);

        //리더보드에 본인의 점수를 입력 (현재 1000점을 입력하겠다)
        if (GUILayout.Button("ReportLeaderboard_num"))
            GPGSBinder.Inst.ReportLeaderboard(GPGSIds.leaderboard_num, 1000, success => log = $"{success}");

        //타겟 리더보드에 모든 정보를 불러오겠다 ex)철수가 몇점, 영희가 몇점
        if (GUILayout.Button("LoadAllLeaderboardArray_num"))
            GPGSBinder.Inst.LoadAllLeaderboardArray(GPGSIds.leaderboard_num, scores =>
            {
                log = ""; //로그 지우기
                for (int i = 0; i < scores.Length; i++)
                    log += $"{i}, {scores[i].rank}, {scores[i].value}, {scores[i].userID}, {scores[i].date}\n";
            });

        
        // 타겟 리더보드에 아이디를 넣고, 몇개까지 표시될건지(10) 어디서부터 스타트할건지  PlayerCentered 플레이어가 중앙
        if (GUILayout.Button("LoadCustomLeaderboardArray_num"))
            GPGSBinder.Inst.LoadCustomLeaderboardArray(GPGSIds.leaderboard_num, 10,
                GooglePlayGames.BasicApi.LeaderboardStart.PlayerCentered, GooglePlayGames.BasicApi.LeaderboardTimeSpan.Daily, (success, scoreData) =>
                {
                    log = $"{success}\n";
                    var scores = scoreData.Scores;
                    for (int i = 0; i < scores.Length; i++)
                        log += $"{i}, {scores[i].rank}, {scores[i].value}, {scores[i].userID}, {scores[i].date}\n";
                });
        
        //이벤트의 값을 증가시킨다. 1씩
        if (GUILayout.Button("IncrementEvent_event"))
            GPGSBinder.Inst.IncrementEvent(GPGSIds.event_enevt, 1);
        
        //이벤트를 불러와서 성공 여부와 이벤트의 이름과 현재 카운트를 보겠다.
        if (GUILayout.Button("LoadEvent_event"))
            GPGSBinder.Inst.LoadEvent(GPGSIds.event_enevt, (success, iEvent) =>
            {
                log = $"{success}, {iEvent.Name}, {iEvent.CurrentCount}";
            });

        //이벤트를 리스트(iEvents)로 반환 받아서 보겠다
        if (GUILayout.Button("LoadAllEvent"))
            GPGSBinder.Inst.LoadAllEvent((success, iEvents) =>
            {
                log = $"{success}\n";
                foreach (var iEvent in iEvents)
                    log += $"{iEvent.Name}, {iEvent.CurrentCount}\n";
            });

        GUILayout.Label(log);
    }*/
}
728x90
반응형
LIST

댓글