Unity Cloud Gamecenter 연결 관련 해결

2024. 2. 19. 10:00·게임 관련/유니티
반응형

안녕하세요

unity cloud 연결을 위해 Apple Gamekit Plugin을 사용해보았지만

여러 이슈들로 인해 현재 이용이 어려워서 우회하는 방법을 이전 포스팅에 소개해드렸는데요

https://horae.tistory.com/1124

 

Unity Cloud Autenticator Game Center 연동시 발생하는 에러 해결

안녕하세요 오늘은 unity cloud authenticator Gamecenter 연동 과정중에 잘 안되는 부분을 해결하고자 하였고 어느정도 우회 방법을 찾았습니다. 우선 Unity에서는 Apple.gamekit을 이용한 연동 방식을 가이드

horae.tistory.com

오늘은 세부 설정 방법에 대하여 소개해드리려고 해요 

1. Asset/Plugin/iOS 폴더 밑에 .m 파일 생성 한다.

구체적으로 c#스크립트를 먼저 생성 후 확장자 이름을 .m으로 변경해줘야 한다. (finder에서 변경) 

변경 이후 기존 c# .meta 파일은 삭제

 

.m 파일에 아래 코드 삽입

#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>

typedef void (*IdentityVerificationSignatureCallback)(const char * publicKeyUrl, const char * signature, int signatureLength, const char * salt, int saltLength, const uint64_t timestamp, const char * error);

extern void generateIdentityVerificationSignature(IdentityVerificationSignatureCallback callback) {
    
    GKLocalPlayer * localPlayer = [GKLocalPlayer localPlayer];

    NSLog(@"LocalPlayer: %@", localPlayer.playerID);
    
    [localPlayer fetchItemsForIdentityVerificationSignature:^(NSURL * _Nullable publicKeyURL, NSData * _Nullable signature, NSData * _Nullable salt, uint64_t timestamp, NSError * _Nullable error) {

        NSLog(@"Received 'generateIdentityVerificationSignature' callback, error: %@", error.description);

        // Create a pool for releasing the resources we create
        @autoreleasepool {
            
            // PublicKeyUrl
            const char * publicKeyUrlCharPointer = NULL;
            if (publicKeyURL != NULL)
            {
                const NSString * publicKeyUrlString = [[NSString alloc] initWithString:[publicKeyURL absoluteString]];
                publicKeyUrlCharPointer = [publicKeyUrlString UTF8String];
            }


            // Signature
            const char * signatureBytes = (char*)[signature bytes];
            int signatureLength = (int)[signature length];

            // Salt
            const char * saltBytes = (char*)[salt bytes];
            int saltLength = (int)[salt length];

            // Error
            const NSString * errorString = error.description;
            const char * errorStringPointer = [errorString UTF8String];

            // Callback
            callback(publicKeyUrlCharPointer, signatureBytes, signatureLength, saltBytes, saltLength, timestamp, errorStringPointer);
        }
    }];
}

 

 

2. 위에서 만든 코드를 실제 호출하는 코드 이며, .cs파일에 넣는다. 

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void IdentityVerificationSignatureCallback(
        string publicKeyUrl, 
        IntPtr signaturePointer, int signatureLength,
        IntPtr saltPointer, int saltLength,
        ulong timestamp,
        string error);

    [DllImport("__Internal")]
    public static extern void generateIdentityVerificationSignature(
        [MarshalAs(UnmanagedType.FunctionPtr)]IdentityVerificationSignatureCallback callback);

// Note: This callback has to be static because Unity's il2Cpp doesn't support marshalling instance methods.
    [MonoPInvokeCallback(typeof(IdentityVerificationSignatureCallback))]
    public static void OnIdentityVerificationSignatureGenerated(
        string publicKeyUrl, 
        IntPtr signaturePointer, int signatureLength,
        IntPtr saltPointer, int saltLength,
        ulong timestamp,
        string error)
    {
        // Create a managed array for the signature
        var signature = new byte[signatureLength];
        Marshal.Copy(signaturePointer, signature, 0, signatureLength);

        // Create a managed array for the salt
        var salt = new byte[saltLength];
        Marshal.Copy(saltPointer, salt, 0, saltLength);

        UnityEngine.Debug.Log($"publicKeyUrl: {publicKeyUrl}");
        UnityEngine.Debug.Log($"signature: {signature.Length}");
        UnityEngine.Debug.Log($"salt: {salt.Length}");
        UnityEngine.Debug.Log($"timestamp: {timestamp}");
        UnityEngine.Debug.Log($"error: {error}");
    }

 

3. 해당 코드를 호출 및 사용 하도록 코드 구성

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void IdentityVerificationSignatureCallback(
        string publicKeyUrl,
        IntPtr signaturePointer, int signatureLength,
        IntPtr saltPointer, int saltLength,
        ulong timestamp,
        string error);

    [DllImport("__Internal")]
    public static extern void generateIdentityVerificationSignature(
        [MarshalAs(UnmanagedType.FunctionPtr)] IdentityVerificationSignatureCallback callback);

    // Note: This callback has to be static because Unity's il2Cpp doesn't support marshalling instance methods.
    [MonoPInvokeCallback(typeof(IdentityVerificationSignatureCallback))]
    public static void OnIdentityVerificationSignatureGenerated(
        string publicKeyUrl,
        IntPtr signaturePointer, int signatureLength,
        IntPtr saltPointer, int saltLength,
        ulong timestamp,
        string error)
    {
        // Create a managed array for the signature
        var signature = new byte[signatureLength];
        Marshal.Copy(signaturePointer, signature, 0, signatureLength);

        // Create a managed array for the salt
        var salt = new byte[saltLength];
        Marshal.Copy(saltPointer, salt, 0, saltLength);


        string time = timestamp.ToString();
        UnityEngine.Debug.Log($"horae:: publicKeyUrl: {publicKeyUrl}");
        UnityEngine.Debug.Log($"horae:: signature.length: {signature.Length}");
        UnityEngine.Debug.Log($"horae:: salt.length: {salt.Length}");
        UnityEngine.Debug.Log($"horae:: string timestamp: {time}");
        UnityEngine.Debug.Log($"horae:: ulong timestamp: {timestamp}");
        UnityEngine.Debug.Log($"horae:: error: {error}");
        UnityEngine.Debug.Log($"horae:: signature: {BitConverter.ToString(signature).Replace("-", "")}");
        UnityEngine.Debug.Log($"horae:: salt: {BitConverter.ToString(salt).Replace("-", "")}");
        UnityEngine.Debug.Log($"horae:: signature base64: {Convert.ToBase64String(signature)}");
        UnityEngine.Debug.Log($"horae:: salt base64: {Convert.ToBase64String(salt)}");
        Task task = SignInWithAppleGameCenterAsync(Convert.ToBase64String(signature), Social.localUser.id, publicKeyUrl, Convert.ToBase64String(salt), timestamp);
    }


    public void StartIdentityVerification()
    {
        // 네이티브 코드에게 인증 서명을 생성하도록 요청합니다.
        generateIdentityVerificationSignature(OnIdentityVerificationSignatureGenerated);

   

    }


    public static async Task SignInWithAppleGameCenterAsync(string signature, string teamPlayerId, string publicKeyURL, string salt, ulong timestamp)
    {

        Debug.Log("horae:: SignInWithAppleGameCenterAsync");
        Debug.Log("horae:: SignInWithAppleGameCenterAsync signature: " + signature);
        Debug.Log("horae:: SignInWithAppleGameCenterAsync teamPlayerId: " + teamPlayerId);
        Debug.Log("horae:: SignInWithAppleGameCenterAsync publicKeyURL: " + publicKeyURL);
        Debug.Log("horae:: SignInWithAppleGameCenterAsync salt: " + salt);
        Debug.Log("horae:: SignInWithAppleGameCenterAsync timestamp: " + timestamp);
        try
        {
            Debug.Log("horae:: try await SignInWithAppleGameCenterAsync");
            await AuthenticationService.Instance.SignInWithAppleGameCenterAsync(signature, teamPlayerId, publicKeyURL, salt, timestamp);
            UnityEngine.Debug.Log("horae:: SignIn is successful.");
        }
        catch (AuthenticationException ex)
        {
            // Compare error code to AuthenticationErrorCodes
            // Notify the player with the proper error message
            Debug.Log("horae:: AuthenticationException");
            Debug.LogException(ex);
        }
        catch (RequestFailedException ex)
        {
            // Compare error code to CommonErrorCodes
            // Notify the player with the proper error message
            Debug.Log("horae:: RequestFailedException");
            Debug.LogException(ex);
        }
    }

 

4. 이제 StartIdentityVerification() 함수를 호출해주면 Gamecenter 로 로그인한 유저를

Unity Cloud로 연결해준다.

 

AppleGamecenterHandler.Instance.GameCenterInit();
AppleGamecenterHandler.Instance.StartIdentityVerification();

 

GamecenterInit()은 아래와 같이 구성되어 있다

 public void GameCenterInit()
    {
        DontDestroyOnLoad(gameObject);
        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
        {
            if (task.Exception != null)
            {
                Debug.LogError($"Failed to initialize Firebase with {task.Exception}");
                return;
            }

            auth = FirebaseAuth.DefaultInstance;

            OnFirebaseInitialized.Invoke();
        });

        GameCenterLogin();
    }

    /// <summary>
    /// Apple GameCenter Login
    /// </summary>
    public void GameCenterLogin()
    {





        if (Social.localUser.authenticated == true)
        {
            Debug.Log("Success to true");
        }
        else
        {
            Social.localUser.Authenticate((bool success) =>
            {
                if (success)
                {
                    Debug.Log("Success to authenticate");
                }
                else
                {
                    Debug.Log("Faile to login");
                }
            });
        }
    }

 

5. Unity Cloud 연동 확인

반응형
저작자표시 비영리

'게임 관련 > 유니티' 카테고리의 다른 글

[유니티 xcode]Invalid Bundle. The bundle at 'CuteMaze.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.  (0) 2024.06.09
FBLPromises Framework not found 에러 문제 해결 방법  (0) 2024.05.14
Unity Cloud Autenticator Game Center 연동시 발생하는 에러 해결  (0) 2024.02.15
[Unity] 유니티 환경에서 android Debug 진행하는 방법  (0) 2024.01.30
ios admob 테스트 기기 등록 방법  (0) 2024.01.17
'게임 관련/유니티' 카테고리의 다른 글
  • [유니티 xcode]Invalid Bundle. The bundle at 'CuteMaze.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.
  • FBLPromises Framework not found 에러 문제 해결 방법
  • Unity Cloud Autenticator Game Center 연동시 발생하는 에러 해결
  • [Unity] 유니티 환경에서 android Debug 진행하는 방법
호레
호레
창업 / IT / 육아 / 일상 / 여행
    반응형
  • 호레
    Unique Life
    호레
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 법률
        • 기본
        • 개인정보보호법
        • 정보통신망법
        • 전자금융거래법
        • 전자금융감독규정
        • 신용정보법
        • 온라인투자연계금융업법
      • 창업
        • 외식업 관련
        • 임대업 관련
        • 유통업 관련
        • 세무 관련
        • 마케팅 관련
        • 기타 지식
        • 트렌드
        • Youtube
      • IT기술 관련
        • 모바일
        • 윈도우
        • 리눅스
        • MAC OS
        • 네트워크
        • 빅데이터 관련
        • A.I 인공지능
        • 파이썬_루비 등 언어
        • 쿠버네티스
        • 기타 기술
      • 퍼블릭 클라우드 관련
        • Azure
        • GCP
        • AWS
      • 정보보안 관련
        • QRadar
        • Splunk
        • System
        • Web
      • 기타
        • 세상 모든 정보
        • 서적
      • 게임 관련
        • 유니티
      • 부동산
      • 맛집 찾기
        • 강남역
        • 양재역
        • 판교역
        • ★★★★★
        • ★★★★
        • ★★★
        • ★★
        • ★
      • 결혼_육아 생활
        • 리얼후기
        • 일상
        • 육아
        • 사랑
        • Food
      • 영어
        • 스피킹
        • 문법
        • 팝송
        • 영화
      • K-컨텐츠
        • 드라마
        • 영화
        • 예능
      • 독서
      • 프로젝트 관련 조사
        • 시스템 구축
        • 로그 관련
        • 웹
        • APT
        • 모의 해킹
        • DB
        • 허니팟
        • 수리카타
        • 알고리즘
        • FDS
      • 기업별 구내 식당 평가
        • 한국관광공사
        • KT telecop
        • KT M&S
        • KT powertel
        • KT cs 연수원
        • 진에어
      • 대학 생활
        • 위드윈연구소
        • 진로 고민
        • 채용정보
        • 자동차
        • 주식
        • 악성코드
        • 게임 보안
      • 쉐어하우스
  • 블로그 메뉴

    • 홈
    • 게임 관련
    • IT 기술 관련
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    돈까스
    상호관세
    대통령
    복리후생
    마케팅
    판교맛집
    쥬쥬랜드
    AWS
    무역전쟁
    수제버거
    유니티
    런치
    판교
    점심
    이재곧죽습니다
    보안가이드
    맛집
    판교역
    수제버거맛집
    수제버거존맛
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
호레
Unity Cloud Gamecenter 연결 관련 해결
상단으로

티스토리툴바