반응형

안녕하세요

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 연동 확인

반응형
반응형

안녕하세요

오늘은 unity cloud authenticator

Gamecenter 연동 과정중에 잘 안되는 부분을 해결하고자 하였고 어느정도 우회 방법을 찾았습니다.

우선 Unity에서는 Apple.gamekit을 이용한 연동 방식을 가이드 하고 있습니다.

https://docs.unity.com/ugs/en-us/manual/authentication/manual/platform-signin-apple-game-center

 

하지만 해당 방법으로 진행하려고 하면 dllnotfound 가 나오던가 아니면, entrypoint를 못찾는 이슈에 도달하게 됩니다.

관련하여 여러 커뮤니티를 찾아보았고 Unity 기술자는 해당 문제에 대해 Apple에 고쳐달라고 얘기하였다고 합니다. 

해당 링크중에 다른 방법으로 unitycloud 연동방식을 해결한 사람이 있었습니다.

 https://gist.github.com/BastianBlokland/bbc02a407b05beaf3f55ead3dd10f808

Publickey url, signature, salt and timestamp 값만 있으면 

unity cloud에서 제공하는 코드로 연동이 가능합니다!!

바로 아래 코드에 인자 값으로 들어가게 되는거지요

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

 

그래서 저는 아래와 같이 코드를 추가해보았답니다. 

자세한 내용은 아래 포스팅을 참고해주세요

https://horae.tistory.com/1125

 

Unity Cloud Gamecenter 연결 관련 해결

안녕하세요 unity cloud 연결을 위해 Apple Gamekit Plugin을 사용해보았지만 여러 이슈들로 인해 현재 이용이 어려워서 우회하는 방법을 이전 포스팅에 소개해드렸는데요 https://horae.tistory.com/1124 Unity Clo

horae.tistory.com

 

참고

https://forum.unity.com/threads/apple-unity-plugins-crashing-on-authentication.1450414/#post-9424940

https://forum.unity.com/threads/apple-unity-plugins-crashing-on-authentication.1450414/#post-9424940

https://docs.unity.com/ugs/en-us/manual/authentication/manual/platform-signin-apple-game-center

https://docs.google.com/document/d/18IfxMcaYCoCHgFrMmM4gfGCHcKKnYx9iCr6DFBU-nLg/edit#heading=h.nh5j6ob4nbj3

I have the same problem,
fetchItems()
OnSuccess()
Thread 1: EXC_BAD_ACCESS (code=257, address=0x2) error, it just crashes when cuts connection from the device to XCode
if not cut connection, it will keep stay in this error line in Xcode
using Unity 2021.3.9f, build on iOS,
manually modified manifest.json to use unity authentication 2.4.0
using Apple Game Center plugin for unity

반응형
반응형

안녕하세요

오늘은 리즈 시절 손예진 / 정우성을 볼 수 있는 영화를 소개하려고 해요 

 

2004년 개봉한 영화이고 현재까지 뜨겁게 사랑 받고 있는 영화에요

 

 

관련하여 핵심 내용에 대하여 리뷰한 유튜브 내용 공유 드릴게요

https://youtu.be/Udg72KYEIwQ

 

반응형
반응형

[unity/android] android에서 Debug.Log() 로그 출력하기

 

#방법은 2가지가 있다.

1.cmd 환경에서 아래 명령어를 입력한다.

adb logcat -s Unity

#다음과 같이 logcat을 볼 수 있다.

 

2.유니티 툴에서 [windows]->[Package Manager] 에서 [android Logcat] 설치

 

[Windows]->[Analsis] ->[android Logcat] 창 실행

#모바일에서 환경에서 디버깅이 가능하다.

 

#unity #유니티 #debug #log #debugging #디버깅 #로그 #안드로이드 #android 

 

 

출처: https://gofogo.tistory.com/70

 

 

반응형

+ Recent posts