유니티

[유니티] 카카오 로그인 연동 feat. 안드로이드

VicGameStudio_Choi 2024. 10. 27. 04:24

글을 안 쓴지 꽤 오래됬는데.. 이번에 한 삽질은 유독 날 괴롭혔기 때문에 글을 남기려고 한다.

 

 

 

유니티 카카오 로그인이 짜증나는 이유.

카카오에서 유니티에서 바로 사용할 수 있는 플러그인을 제공해주지 않아서

직접 플러그인을 만들어서 연동해야한다.

 

위에서 말한 '플러그인' 이란, 네이티브 코드(안드로이드 자바 or 코틀린 코드)를 사용할 수 있게하는 중간 다리 코드이다.

유니티 코드인데, 유니티 코드에서 자바나 코틀린 코드를 불러올 수 있다.

 

 

 

 

 

 

과정

1. 카카오 SDK 설치를 위해 File > Build Settings > Player Settings > Publishing Settings

 

 

2. 안드로이드 프로젝트(Empty Project)를 생성한다.

 

 

 

3. Settings.gradle. maven 추가

maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
    }
}

 

 

 

4. 프로젝트 내부에서 모듈을 생성한다. (https://saakmiso.tistory.com/26)

 

KakaoLoginModule 프로젝트 안에 하위로 unity-kakao-login 모듈을 넣는다. ( 이름은 똑같을 필요없이 마음대로 해도된다.)

 

 

 

 

 

5. 해당 모듈의 build.gradle 을 수정한다.

모듈을 라이브러리롤 쓸 것이기 때문에 plugins에 한 줄 추가.

 

    id 'com.android.library'
plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
}

 

dependencies 에 아래 두 줄을 추가한다.

api 가 아니고 implementation 을 써도 될 것 같다.

api 를 쓴 이유는 아래에서 설명하도록 하겠다.

 

dependencies {
    api  "org.jetbrains.kotlin:kotlin-stdlib:1.7.20"
    api  "com.kakao.sdk:v2-user:2.20.6"
    compileOnly files('libs/classes.jar')

 

요거를 쓰는 이유는 classes.jar 이 유니티에 포함시켜면서 중복 에러가 나기때문에 모듈 빌드에는 포함시키지 않는다.

compileOnly files('libs/classes.jar')

 

 

 

6. 유니티 classes.jar 을 가져온다. 

 

대신에 모듈에 libs 에 추가해야한다. 

 

 

왜 요걸 가져오냐면, 안드로이드 모듈에서 로그인하고, 유니티 쪽으로 로그인 완료했다는 신호를 전달해야하지 않겠는가?

아래 링크에서 잘 설명하고 있다.

https://return-1.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-jar-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-%EC%83%9D%EC%84%B1%EB%B0%A9%EB%B2%95

 

유니티 안드로이드 JAR 플러그인 생성방법 (Unity Android Plugin JAR)

Unity 게임 개발 중 안드로이드 폰에서 안드로이드만의 특정 기능이 필요할 때가 있는데 이때 안드로이드 JAR 플러그인 생성 방법을 알아보도록 하겠습니다. 안드로이드 스튜디오에서 새프로젝트

return-1.tistory.com

 

 

 

7. 키해시를 얻는다. 유니티 프로젝트의 키해시를 얻어야함.

 

 

위의 방법이 귀찮으면.. 구글링하면 방법은 참 많이 나온다..

 

 

 

8. 카카오 개발자센터에 플랫폼에 안드로이드를 등록한다. 

 

 

 

9. 안드로이드를 등록하면서 얻어온 키해시도 같이 등록함.

 

 

 

 

 

10.  로그인 활성화

 

 

 

 

 

 

 

11. 유니티에서도 똑같이 maven 이랑 dependencies 에 카카오 sdk 를 추가해야한다.

 

웃긴게.. 모듈에서 이미 카카오 sdk 를 다운받는 dependencies 가 들어가는데

왜 유니티에서도 똑같은 sdk 를 받아야하나..? 2개가 중복되지 않을까?

 

하지면 정말 욕나오게도.. 모듈은 sdk 다운을 못한다? 라는게 chatgpt 의 말이다.

물론, 방법은 있는데 엄청 귀찮다. 차라리 유니티에서 받자.(chatgpt 는 implementation 대신 api 를 쓰면 된다했는데 안됨;;)

 

  • 유니티 baseProjectTemplate.gradle 에 추가함.
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' } // Kakao SDK 저장소

 

 

  • 유니티 mainTemplate.gradle 에도 추가함.
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.20" // <= 요거는 기억 안 나는데 같이 추가해주자.
implementation "cohttp://m.kakao.sdk:v2-user:2.20.6" // 카카오 로그인 API 모듈

 

  • 유니티 gradleTemplate 에 추가
    • android.useAndroidX=true

 

 

 

 

 

12.  유니티 AndroidManifest.xml

 

  • 권한 추가
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

 

  • 아래 activity 추가. 요거 추가 안 해서 1주일 삽질했다. 그대로 추가해야한다.
  • 대신에 scheme 쪽에 kakao{네이티브키} 는 카카오 개발자 센터에 있는거 넣으면 됨.
  • com.kakao.sdk.auth.AuthCodeHandlerActivity  <= 이름 마음대로 바꾸지말고 그대로 넣어야함.
  • 이게 웹으로 로그인하고 무조건 해당 액티비티로 스킴을 날리게 되어있어서 저걸 바꿔버리면
  • '로그인하기' 버튼 누르고 응답이 없음 ㅇㅋ?
<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<!-- Redirect URI: "kakao${NATIVE_APP_KEY}://oauth" -->
<data android:host="oauth"
                    android:scheme="kakao{네이티브코드}" />   
</intent-filter>
</activity>

 

 

 

 

 

 

 

 

13. 안드로이드로 돌아와서 코드를 넣는다.

package com.vicgamestudios.unity_kakao_login

import android.util.Log
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.KakaoSdk
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.common.util.Utility
import com.kakao.sdk.user.UserApiClient
import com.unity3d.player.UnityPlayer

class KakaoLoginManager {
    fun initKakaoSdk(){
        val context = UnityPlayer.currentActivity;
        Log.i("UnityLog", "카카오 초기화 시작")
        KakaoSdk.init(context, "{네이티브키}") // 중괄호 생략하고 넣으면됨.
    }

    fun loginWithKakao()
    {
        Log.i("UnityLog", "로그인 시작")
        val context = UnityPlayer.currentActivity;

        val onResult : (OAuthToken?, Throwable?) -> Unit = {token, error ->
            if(error != null) {
                UnityPlayer.UnitySendMessage("KakaoLoginManager", "OnLoginFailed", error.message)
                Log.e("UnityLog", "카카오톡 로그인 실패", error)
            }
            else if(token != null) {
                UnityPlayer.UnitySendMessage(
                    "KakaoLoginManager",
                    "OnLoginSuccess",
                    token.accessToken
                )
                Log.e("UnityLog", "로그인 성공 ${token.accessToken}")
            }
        }

        if(UserApiClient.instance.isKakaoTalkLoginAvailable(context)){
            Log.i("UnityLog", "isKakaoTalkLoginAvailable 시작")
            UserApiClient.instance.loginWithKakaoTalk(context){token, error ->
                if(error != null){
                    Log.e("UnityLog", "카카오톡 로그인 실패", error);

                    if(error is ClientError && error.reason == ClientErrorCause.Cancelled)
                    {
                        UnityPlayer.UnitySendMessage("KakaoLoginManager", "OnLoginFailed", error.message)
                        return@loginWithKakaoTalk;
                    }

                    UserApiClient.instance.loginWithKakaoAccount(context, callback = onResult)
                }
                else if(token != null){
                    Log.i("UnityLog", "카카오톡 로그인 성공 ${token.accessToken}");
                    UnityPlayer.UnitySendMessage(
                        "KakaoLoginManager",
                        "OnLoginSuccess",
                        token.accessToken
                    )
                }
                else{
                    Log.i("UnityLog", "띠용");
                }
            }
        }
        else {
            Log.i("UnityLog", "loginWithKakaoAccount 시작")
            UserApiClient.instance.loginWithKakaoAccount(context, callback = onResult)
        }
    }
}

 

 

 

 

 

14. 유니티 코드 추가

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

public class KakaoLoginManager : MonoSingleTon<KakaoLoginManager>
{
    Coroutine _coWaitLogin = null;

    string className = "패키지명.unity_kakao_login.KakaoLoginManager";
    // 자기거에 맞게 수정한다.
    AndroidJavaObject _androidJavaObject;

    private void Awake()
    {
        _androidJavaObject = new AndroidJavaObject(className);
    }

    public void ResetAll()
    {
        _coWaitLogin = null;
    }

	// 사실 코루틴 탈 필요없는데.. 테스트용이라 걍 써도됨.
    IEnumerator CoWaitLogin()
    {
        yield return new WaitForSeconds(0.1f);

        try
        {
            _androidJavaObject.Call("initKakaoSdk");
            _androidJavaObject.Call("loginWithKakao");
        }
        catch (System.Exception e)
        {
            Debug.LogError("Kakao Login failed: " + e.Message);
        }

        _coWaitLogin = null;
    }

    // 카카오 로그인 호출
    public void LoginWithKakao()
    {
        if(_coWaitLogin != null)
            return;

        _coWaitLogin = StartCoroutine(CoWaitLogin());
    }

    // 카카오 로그아웃 호출
    public void LogoutFromKakao()
    {
        try
        {
            AndroidJavaClass kakaoLogin = new AndroidJavaClass(className);

            // Android의 로그아웃 메소드 호출
            kakaoLogin.CallStatic("logout");
        }
        catch (System.Exception e)
        {
            Debug.LogError("Kakao Logout failed: " + e.Message);
        }
    }

    // 로그인 성공 시 호출되는 메서드
    public void OnLoginSuccess(string token)
    {
        Debug.Log("Kakao Login Success! Token: " + token);
    }

    // 로그인 실패 시 호출되는 메서드
    public void OnLoginFailed(string error)
    {
        Debug.LogError("Kakao Login Failed: " + error);
    }

    // 로그아웃 성공 시 호출되는 메서드
    public void OnLogoutSuccess(string message)
    {
        Debug.Log("Kakao Logout Success: " + message);
    }

    // 로그아웃 실패 시 호출되는 메서드
    public void OnLogoutFailed(string error)
    {
        Debug.LogError("Kakao Logout Failed: " + error);
    }
}

 

 

 

 

 

15. 모듈을 생성한다.

 

  • Release 로 모듈을 생성한다. 빠른게 좋은거니까 ㅎㅎ
  • 모듈을 생성할 때 생성하려는 모듈을 클릭하고.. (unity-kakao-login 을 클릭함)
  • Build > Select Build Variant 를 클릭.
  • 그러면 아래에 app:unity-kakao-login 이 나오는데 요놈을 release 로 바꿔준다.

 

 

 

  • 모듈 클릭 > Build > Make Module 을 선택하면 빌드가됨.

 

 

 

 

 

 

 

 

16. 유니티로 옮긴다.

 

17. 유니티 빌드 돌려서 테스트 ㄱㄱ