안녕하세요? 글뻥입니다.
한 이틀 정도 이클립스 공부하고 강좌 올립니다. =)
틀려도 뭐라 하지마세염 ㅡㅡ;;
안드로이드 연동 이슈땜시 돌아 버릴려해서, 아무 생각없이 여기 저기 자료 찾아서 연동해봤습니다.
유니티가 자바를 연동하는 방식은 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

트랙백 주소 :: 이 글에는 트랙백을 보낼 수 없습니다