안녕하세요? 글뻥입니다.
어제에 이어서 오늘은  AC2 도반이신 이문상님 붙잡고... 야외카페에서 어떻게 Jar파일을 통합할지 같이 스타디한(라고 쓰고 지도 받았다고 읽습니다. ㅋ) 결과를 공유 드립니다.
아울러 출처를 밝히지 않은 불펌은 절대 불허합니다.
펌하실때 반드시 unitystudy.net 또는 wolfpack.pe.kr 을 밝혀주세요.
(링고게임즈의 지적 자산을 지켜주시길 부탁드립니다.)
어제 이클립스에 포팅한 녀석을 그대로 재활용할 예정입니다. =)
먼저 왼쪽 Navigator에서 New > Android Application Project를 클릭합니다.
사용자 삽입 이미지

Create custom launcher icon만 언체크하고 Next
사용자 삽입 이미지

그냥 막 넘어갑니다.
사용자 삽입 이미지

Finish 클릭!
사용자 삽입 이미지

새로 만든 프로젝트의 src 폴더를 타고 들어가 Class를 새로 만듭니다.
사용자 삽입 이미지
저는 ExtJarTest로 설정했어요.
사용자 삽입 이미지

사용할지 안할지는 모르겠지만... 하두 디인 "AndroidManifest.xml"라는 넘을 안전빵으로 새로만든 클래스명으로 수정했습니다.
사용자 삽입 이미지

어제 만든 AndroidTest 프로젝트에서 class.jar 파일을 복사하여 새로 만든 프로젝트에 넣어주세요.
사용자 삽입 이미지
Ctrl+c, Ctrl+v해도 됩니다. =)
사용자 삽입 이미지
그리고 새로 만든 프로젝트의 Properties를 클릭!
사용자 삽입 이미지
Java Build Path에서 Libraries 탭에 Add Jars를 클릭
사용자 삽입 이미지


방금 복사한 Class.Jar파일을 선택해 줍니다.
사용자 삽입 이미지

그리고 새로 만든 ExtJarTest 소스를 어제와 같이 수정해줍니다.
extJarCall이라는 메소드를 만들었고 거기에 String 데이터를 넣으면 " Called!"라는 메시지를 붙여서 반환하는 구조입니다.
사용자 삽입 이미지

소스가 있는 폴더에 우클릭하시고 Export합니다.
사용자 삽입 이미지


Java에 Jar file선택!
사용자 삽입 이미지

다음과 같이 소스 폴더만 선택하고 나머지는 다 무시.
Export할 경로는 어제 Export해둔 (지난강좌 참조) 프로젝트의 Lib 폴더로...
사용자 삽입 이미지
다음과 같이 Export되면 성공입니다. =)
사용자 삽입 이미지
이제 어제 (지난강좌)의 프로젝트를 선택하고 속성을 눌러 줍니다.
사용자 삽입 이미지
Add Jars하시고 방금 들어온 ExtJar.jar 파일을 선택!
사용자 삽입 이미지
이렇게 들어오면 성공입니다.
사용자 삽입 이미지
어제 소스를 약간 수정해서 ExtJarTest.extJarCall() 메소드를 호출해줍니다.
사용자 삽입 이미지
이제 이클립스에서 빌드하면~~~~
유니티에서 자바로 보낸 문자에 Called!라는 문자열이 잘붙어서 따라옵니다. =)
사용자 삽입 이미지


오늘도 고생많으셨습니다.
이 땅의 모든 개발자분들 기운내세여 =)
마지막으로 바쁘신내주셔서 친절히 답변해 주신 이득우님께도 감사드립니다. =)
2013/05/06 22:58 2013/05/06 22:58
안녕하세요? 글뻥입니다.
한 이틀 정도 이클립스 공부하고 강좌 올립니다. =)
틀려도 뭐라 하지마세염 ㅡㅡ;;
안드로이드 연동 이슈땜시 돌아 버릴려해서, 아무 생각없이 여기 저기 자료 찾아서 연동해봤습니다.
유니티가 자바를 연동하는 방식은 2가지가 있어요.
1. 유니티를 Eclipse로 Export 해서 일부 Class.jar 파일을 뽑은 후에 원하는 대로 Class를 만들어서 다시 Plugin현태로 붙이는 방법
2. 유니티를 Eclipse로 Export한 후에 그 안에서 삽질하는 방법
첫번째는 주로 유료플러그인에서 많이 쓰는 방식이고, 플러그인 만들거 아니니까 포기하고 바로 2번째로 가봅시다.
(사실은 첫번째로 OO 붙이다가 울 이사님 좌절... 옆에서 겜 만드는 저도 좌절... 그래서 겜 만드는 거 급 포기하고 OO붙이는 작업 긴급 붙음... 뭐 이런 시나리오 되겠슴돠..)
암튼 각설하고 유니티를 열고 새로 프로젝트를 만들어요.
그리고 아무 생각하지 말고 게임오브젝트로 GUI TEXT를 넣습니다.
사용자 삽입 이미지

이름을 "TEST"로 변경합니다.
사용자 삽입 이미지

이제 자바파일을 호출할 녀석을 만듭니다.
저는 TestMethod라는 이름으로 스크립트를 하나 만들었습니다.
using UnityEngine;
using System.Collections;

public class TestMethod : MonoBehaviour {

//    public AndroidJavaObject activity;


// 시작하면 자바에 있는 메소드를 호출합니다. 기억합시다. "initActivity"!!!!!
void Start () {
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                jo.Call("initActivity", "unity to android"); //여기가 젤 중요함!
            }
        }
}

//여기는 자바가 호출하는 메소드입니다.
    public void AndroidLog (string a)
    {
        transform.GetComponent<GUIText>().text = a;
}
}
위에 Start땜시 멘붕이 왔죠.
"ㅅㅂ 당췌 이걸 어떻게 찾는고야!!?!!"
하지만, 유니티는 똑똑합니다... UnityPlayerActivity를 상속받은 넘들은 무조건 그냥 이게 먹힙니다.
물론, Manifest에서 설정해줘야 하지만... 설정법은 좀있다 다시 거론하면서 일단 여기까지 하고 넘어갑시다.
그리고 아까 만들어둔 TEST에 Attach합니다.
Player Setting에서는 다음과 같이 설정했습니다.
사용자 삽입 이미지

그리고 인증키도 생성해줬습니다. Create New Keystore를 클릭하시면 됩니다.
사용자 삽입 이미지

이제 Eclipse로 Export!
사용자 삽입 이미지

이제 유니티는 잠시 닫아주셔도 좋습니다. =)
안드로이드 SDK가 깔려있는 폴더를 보면... eclipse가 보이실거예요!
사용자 삽입 이미지
이제 eclipse를 살포시 따블클릭!
1. 파일에 Import를 클릭합니다.
사용자 삽입 이미지

Exit 어쩌구 항목을 클릭하구요...
사용자 삽입 이미지

폴더를 선택하면 끝!
사용자 삽입 이미지

좌측 네비게이션바에 주목해주세요!
사용자 삽입 이미지

src라는 폴더를 계속 열어서 타고 들어가면...
사용자 삽입 이미지

파일이 3개보입니다.
ProcyActivity는 버전을 확인해서 버전이 낮은넘은 그냥 Activity로, 높은 넘은 NativeActivity로 보낸다고 합니다.
뭐... 이런게 있구나 정도로 가볍게 쌩까주시고...
파일을 하나 만듭니다.
사용자 삽입 이미지

저는 "TestJava.java"로 생성했지요....
이제 다음의 소스를 부앜~ 긁어다 붙입니다.
package com.lingo.androidtest;
import com.unity3d.player.*;
import android.os.Bundle;
public class TestJava extends UnityPlayerActivity {
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
   
    public void initActivity(final String messageFromUnity)
    {
        runOnUiThread(new Runnable() {
            public void run()
            {
            UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
               }
          });
    }
}
한가지 주의하실점은 UI Thread 테스트를 위해 만든 녀석이
    public void initActivity(final String messageFromUnity)
    {
        runOnUiThread(new Runnable() {
            public void run()
            {
            UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
               }
          });
    }
요 부분입니다. 이걸... Thread가 불필요하다면
    public void initActivity(String messageFromUnity)
    {
    UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
    }
요롷게 고쳐주세요.
암튼 이제 마지막 순서입니다. Manifest라는 아주 지독한 넘을 고쳐야 하죠!
<activity> 테그가 3개 보일텐데 2개는 날려버리시고...
요렇게 생긴넘이 포함된 Activity 테그만 남겨두신뒤에
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
사용자 삽입 이미지
위와 같이 이름만 ".TestJava"로 변경합니다.
이제 실행!
사용자 삽입 이미지


제가 삽질했던 경험에 따라 몇가지 얻은 정보를 이자리에서 공유해야 겠어요.
먼저, 유니티->자바인 경우
가장 먼저 해야 할건...
UnityPlayerActivity 를 확장한 클래스를 main으로 등록해주는 겁니다.
이건 Manifest에서 진행하는 거죠.
다시말해... Manifest에...
<activity android:name=".TestJava" 어쩌구 저쩌구... >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>
의 구조로 사용자가 생성한 Class가 물리지 않으면 Fail!
2번째로 사용자가 확장한 클래스는 반드시...
"public class TestJava extends UnityPlayerActivity" 의 구조여야 한다는 점입니다.
이 정도 상황까지 되면 아래와 같은 코드로 호출이 가능합니다.
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                jo.Call("initActivity", "unity to android"); //여기가 젤 중요함!
            }
        }
물론 위의 코드는 다음과 같이 재정의 될 수 있습니다.
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")
 jo.Call("initActivity", "unity to android");
별도로 오브젝트와 클래스를 찾지않아도 되는 아주 훌륭한 상황되겠습니다.
반대로 자바가 유니티를 호출할때는 다음의 순서로 갑니다.
오브젝트, 메소드명, Argument
따라서, 다음과 같은 코드가 작동할 수 있는 것이죠.
Scene에만 떠 있다면 암생각 없이 작동됩니다.
    UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);


몇 번이나 밥상 엎어 버릴 생각이었는데... 이틀 정도의 삽질로 해결이 되서 다행이네욤.
물론, 플러그인들끼리 Merge하는건 또 다른 문제같습니다.
그롬~ 수고하세욤~
2013/05/06 22:53 2013/05/06 22:53