'자바'에 해당되는 글 2건

  1. 2014/04/10 글뻥 Unity3D Android Plugin 만들기 (2)
  2. 2013/05/06 글뻥 유니티4! 짜증나는 이클립스 연동 한방에 끝내보자. 1/2 (4)
작년 이맘때쯤에 JAVA와 유니티3D를 연동하는 예제를 포스팅하였다.
짜증나는자바1편짜증나는자바2편

자바연동 2편에서 대충 Jar파일을 만들어서 Java에서 호출하는 부분을 만들었었지만, 1편에서 밝힌 바와 같이 Jar를 유니티3D로 끌고 와서 연동하는 예제는 다루지 않았다.

어쩌면... 짜증나는 자바시리즈 3편으로 봐도 될 정도로 오늘 다룰 주제는 자바로 만들어진 Jar파일을 유니티로 가져와서 연동하는 예제이다.

( 출처 밝히면 펌 자유이지만, 출처를 밝히지 않으신다면 고소크리 들어갑니다.)

1. 이클립스를 연다.
2. Android Application Project를 새로 만든다.
사용자 삽입 이미지
3. 이름과 프로젝트명을 지정하고 패키지이름을 지정한다.
사용자 삽입 이미지
4. 이제부터 다음, 다음, 다음, 다음 4연타.
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

5. 프로젝트 생성완료. (쉽죠?)
사용자 삽입 이미지
6. 디버그 설정을 Android Application으로 설정
사용자 삽입 이미지
7. 이제 만들어진 프로젝트명에서 마우스 우클릭후 속성을 클릭
사용자 삽입 이미지
8. "Is Library"체크하고 "Apply" 한번 눌러 준뒤 "OK"
사용자 삽입 이미지
9. 프로젝트 폴더 밑에 /bin 폴더에 보면 "Plugin.jar"파일이 생성되어 있다. (나중에 유니티에서 이녀석을 가져다 쓸거임)
사용자 삽입 이미지
10. /src/com.lingo.plugin을 클릭한 후 다시 우클릭하여 New, Class를 차례대로 클릭
사용자 삽입 이미지
11. 클래스명을 Test로 하고 Finish 클릭
사용자 삽입 이미지
12. 다음과 같이 정적(Static) 메소드와 인스턴스(Static이 안붙은) 메소드를 작성한다.
사용자 삽입 이미지

13. 다음과 같이 Build Automatically 선택되어 있으면 저장과 동시에 자동으로 Build 됨.
     * Console에서 에러가 발생하지 않았다면 문제없이 사용가능한 형태가 됨.
사용자 삽입 이미지

14. 저장하고 빌드가 완료되면 /bin 폴더의 속성을 클릭해서 실제 경로 확인
사용자 삽입 이미지
15. 이제 유니티로 와서 코딩부터...
     * 주의점은 Static은 "AndroidJavaClass"로, 인스턴스는 "AndroidJavaObject"로 선언되어야 함.
사용자 삽입 이미지
18. 다음과 같이 Main Camera와 GUI Text만 배치한다.
사용자 삽입 이미지
19. PluginTest 파일을 Main Camera에 Attach한후 GUI Text를 다시 Asign한다.
     - 물론 /Pluings/Android 밑에 "9"에서 언급한 plugin.jar 파일을 넣어두는걸 잊으면 골룸.
사용자 삽입 이미지
20. GUI Text Default
사용자 삽입 이미지

21. Editor 상에서는 이렇게 보임. (문구가 장난이지만... 진짜 작동하는거 맞다. ㅜㅜ)
사용자 삽입 이미지
이제 마지막으로 Build&Run하면, 안드로이드 폰에서 실행된 결과를 확인할 수 있다.

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