9월, 2013의 게시물 표시

Unity3D 안드로이드 페이스북 R.java 이슈 해결하기

이미지
유니티3D용 페이스북 SDK가 나온 마당에 페이스북 안드로이드 SDK를 유니티에 적용하는 이슈를 정리하자니 살짝 민망하네요 ㅎ; 하지만 지금 정리하는 이슈는 유니티3D용 페이스북 SDK가 나오기전인 5월에 발생했던 facebook java.lang.NoClassDefFoundError: com.facebook.android.R$layout 이슈고 또 굳이 유니티3D가 아니더라도 해당 이슈 발생시 도움들 되시라고 정리를 남겨봅니다.

첫 이슈 포스팅에서도 언급했듯이 위와 같이 중국 블로거 분에게 구글 번역의 힘을 빌어 질문 공세를  했었습니다. 하지만 해결이 안되서 그냥 중국분이 만든 facebook_r.jar 파일을 계속 사용했었죠.

 그러던중 6월말에 어느분의 도움으로 해결이되어 7월부터는 중국분의 jar 파일 없이도 이슈없이 연동이 잘 되고 있는중입니다.


 플러그인 프로젝트를 jar 파일로 익스포트할 때 페이스북 sdk 프로젝트의 gen 폴더도 같이 포함해서 익스포트 해주면 유니티3D 플러그인 폴더에 따로 중국분이 만든 r.jar 없이도 잘 작동합니다. 이런 이슈의 근본적인 원인등은 내부 메커니즘을 몰라 잘 모르겠지만 일단 이렇게 해결을 한 상태입니다.

 조심히 예상해보기로 이런 이슈는 아마 이클립스에서 유니티3D에서 빌드한 임시 안드로이드 프로젝트를 가져다 사용하는 방식으로 빌드하면 발생하지 않을까 추측해봅니다.

Unity3D 91SDK 3.2.6.1 업데이트 변경 작업 사항

이미지
중국 91 마켓 SDK가 3.2.6.1로 9월 4일에 업데이트 넘어왔습니다. 휴가였기 때문에 다음주인 9월 2째주에 작업을 완료하고 추억이다 뭐다해서 이제야 정리를 해봅니다. 지금은 마켓 심의 통과도 한 상태인데 아무튼 업데이트를 자주 해주네요.
툴바 출력 API 추가NdCommplatform.getInstance().ndAppVersionUpdate 삭제됨 NdCommplatform.getInstance().ndInit 시에 앱 업데이트 버전 체크가 자동 처리됨게임 일시정지, Exit 처리  크게 위 2가지 처리를 해주면 됩니다. 유니티3D C#부분은 간단하므로 패스해봅니다.


1. 초기화 및 앱 업데이트 처리

// ND_VERSION_CHECK_LEVEL_STRICT - 업데이트 정보 획득 실패 시 게임 강제 종료.
// ND_VERSION_CHECK_LEVEL_NORMAL - 업데이트 정보 획득 실패 시 그냥 게임 진행.
appInfo.setNdVersionCheckStatus(NdAppInfo.ND_VERSION_CHECK_LEVEL_STRICT);

NdCommplatform.getInstance().ndInit(this, appInfo, new OnInitCompleteListener() {

@Override
protected void onComplete(int arg0) {
// TODO Auto-generated method stub
Log.d(LOG_TAG, "ndInit onComplete " + arg0);
switch(arg0)
{
case OnInitCompleteListener.FLAG_NORMAL:
//초기화 성공
break;
case OnInitCompleteListener.FLAG_FORCE_CLOSE:
// 게임 강제 종료
/*
* - 일반 업데이트를 유저가 취소할 경우, 게임 플레이에 영향주지 않게 처리.
  - 강제 업데이트 요구를 유저가 거부할 경우 , 게임에서는 로그인을 비롯한 프로시져 진행을 거부해야 하며 , 유저에게 업데이트…

Google In-App Billing V3 사용자는 이 항목을 구입할 수 없습니다

이미지
InAppBuyItem_U testinappitem1
PurchaseFragment.handleError: Error: PurchaseError{type=3 subtype=16}
PurchaseFragment.fail: Purchase failed: PurchaseError{type=3 subtype=16}
IabActivity.getResponseCodeFromError: Unexpected PurchasePermissionResponse: 16
java.lang.Exception
at com.google.android.finsky.utils.FinskyLog.wtf(FinskyLog.java:43)
at com.google.android.finsky.billing.lightpurchase.IabActivity.getResponseCodeFromError(IabActivity.java:36)
at com.google.android.finsky.billing.lightpurchase.IabActivity.getResponseCode(IabActivity.java:51)
at com.google.android.finsky.billing.lightpurchase.IabV3Activity.onFinish(IabV3Activity.java:37)
at com.google.android.finsky.billing.lightpurchase.PurchaseActivity.finish(PurchaseActivity.java:133)
at com.google.android.finsky.billing.lightpurchase.PurchaseActivity.onFinished(PurchaseActivity.java:161)
at com.google.android.finsky.billing.lightpurchase.PurchaseFragment.finish(PurchaseFragment.java:811)
at com.google.android.finsky.billing.lightpurchas…

Google In-App Billing V3 Unable to buy item, Error response: 7:Item Already Owned

Starting async operation: launchPurchaseFlow
Constructing buy intent for testinappitem1, item type: inapp
In-app billing error: Unable to buy item, Error response: 7:Item Already Owned
Purchase finished: IabResult: Unable to buy item (response: 7:Item Already Owned), purchase: null
InAppBuyItem_U testinappitem1

 구글 인앱빌링 V3로 비관리 아이템 같은 것을 중복 구매시 위와 같은 오류가 발생합니다. 만약 onIabPurchaseFinished 부분에서 purchase != null 인지 체크하지 않고 샘플과 같게 개발하셨다면 NullPointerException 에러가 발생하게되니 주의하시기 바랍니다.

    // Callback for when a purchase is finished
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            ...

            Log.d(TAG, "Purchase successful.");

            if (purchase.getSku().equals(SKU_GAS)) {
                // bought 1/4 tank of gas. So consume it.
                Log.d(TAG, "Purchase is gas. Starting gas consumption.");
 …

Google In-App Billing V3 onIabPurchaseFinished 중 java.lang.NullPointerException

onActivityResult(10001,0,Intent { (has extras) }
Ending async operation: launchPurchaseFlow
Purchase canceled - Response: 1:User Canceled
Purchase finished: IabResult: User canceled. (response: -1005:User cancelled), purchase: null
Shutting down VM
threadid=1: thread exiting with uncaught exception (group=0x40a3c1f8)
FATAL EXCEPTION: main
java.lang.Error: FATAL EXCEPTION [main]
Unity version     : 4.1.2f1
Device model      : Acer A500
Device fingerprint: acer/a500_ww_cus1/picasso:4.0.3/IML74K/1336617649:user/release-keys
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10001, result=0, data=Intent { (has extras) }} to activity {com.Test.unityandroidfacebookjar/com.Test.unityandroidfacebookjar.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2980)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3023)
at android.app.ActivityThread.access$1100(ActivityThread.java:123…

Unity3D 태국 TDP 결제 WebView로 처리하기

이미지
유니티3D에 태국 True Digital Plus의 모바일 충전 결제를 연동했었는데 그 때는 유니티3D에서 지원하는 Application.OpenURL을 가지고 웹 브라우저를 실행해서 했었는데요 이렇게하면 백 버튼을 눌러 브라우저를 종료하는데 있어 이슈가 발생 되는군요.

 브라우저에서 결제를하고 다른 페이지로 진행이 된 뒤 백버튼을 눌러 다시 게임으로 돌아가야하는데 백 버튼을 누르면 뒤로가기가 되서 다시 결제 페이지로 돌아가는 문제가 있는거죠.


 위 영상은 태국 TDP 결제를 적용한 게임의 결제 진행과정 영상으로 보시면 이해하시는데 도움이 되실 듯 합니다.

 그래서 브라우저를 띄우는것 말고 SDK에 있는 브라우징 기능이 없을까하고 리서치해보니 안드로이드 웹뷰(WebView)라는게 있더군요. 좀 더 리서치를 해보니 GREE에서 Unity3D용 WebView를 만들어 공개했네요. keijiro-san 이라는 일본분의 unity-webview-integration 플러그인을 상속받아서 만들었다고 합니다. 이건 자바 스크립트로 되어있으니 C#으로 되어있는 GREE의 것을 사용하는것을 정리 하겠습니다.

 여담이지만 cocos2d-x에 GREE 연동할 때 수많은 이슈들과 함께 고생을 했었는데 지금보니 GitHub에 GREE Platform SDK for cocos2d-x 가 있네요.


GitHub에 있는 gree의 unity-webview를 다운로드 및 압축해제 후 dist 폴더에 있는 unity-webview.unitypackage를 임포트 합니다. 위 그림과 같이 안드로이드 뿐 아니라 iOS와 MacOS도 지원합니다.


///< WebViewObject 변수를 추가
public WebViewObject webViewObject;

public void RequestPayment(int amount)
{
string strUrl = string.Format("{0}?{1}={2}&{3}={4}&{5}={6}&{7}={8}&{9}={1…

Unity3D Google InApp V3 java.lang.NoClassDefFoundError: com.android.vending.billing.IInAppBillingService$Stub

이미지
cocos2d-x에 구글 인앱 빌링 v2를 연동하고 오랜만에 v3 버전으로 유니티3D에 연동중에 있습니다.

Creating IAB helper.true
Could not find method com.android.vending.billing.IInAppBillingService.consumePurchase, referenced from method com.example.android.trivialdrivesample.util.IabHelper.consume
VFY: unable to resolve interface method 3836: Lcom/android/vending/billing/IInAppBillingService;.consumePurchase (ILjava/lang/String;Ljava/lang/String;)I
VFY: replacing opcode 0x72 at 0x00b6
Could not find method com.android.vending.billing.IInAppBillingService.getBuyIntent, referenced from method com.example.android.trivialdrivesample.util.IabHelper.launchPurchaseFlow
VFY: unable to resolve interface method 3837: Lcom/android/vending/billing/IInAppBillingService;.getBuyIntent (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/os/Bundle;
VFY: replacing opcode 0x78 at 0x0059
Could not find method com.android.vending.billing.IInAppBillingService.getPurchases, referenced from method com.example.android…

Unity3D Baidu Duoku 액티비티 랙 걸리거나 블랙 화면이 뜬다면

이미지
현재는 중국 바이두 Duoku 마켓의 심의를 통과한 상태입니다. 얼마전 바이두 1.1.0 SDK로 업데이트 해달라고 해서 넘겨주고 생긴 이슈중에 바이두의 로그인 액티비티나 인앱결제등의 따로 뜨는 액티비티들이 보여질 때 화면이 랙이 걸리거나 액티비티가 검은색 화면으로만 뜬다는 이슈가 있었습니다.

 저희 사내 테스트에서는 해당 증상이 없는데 유독 중국에서만 이슈라 스샷도 없네요. 일단 바이두에서는 자기들도 3D 게임 연동은 처음이라며 해결책으로 자꾸 빈 액티비티를 SDK api의 인자로 넘기라고 하더군요. 그래서 func( new Activity() ) 뭐 대충 수도코드로 보자면 이런식으로 넘겼는데 다른 오류만 날뿐 해결되지 않았습니다.

 결과적으로 중국 91 마켓 SDK 3.2.5로 버전 업데이트하면서 나왔던 이슈 해결했듯이 액티비티를 위 그림과 같이 추가로 만들어 관련 기능만 간단히 처리하게 해주면 됩니다.

<!-- Duoku -->
<activity android:name="com.wwforever.dk.DuokuLoginActivity" />
<activity android:name="com.wwforever.dk.DuokuPayActivity" />
<activity android:name="com.wwforever.dk.DuokuAccountActivity" />

 AndroidManifest.xml에는 당연히 위와 같이 추가해주고요. 물론 액티비티는 하나만 만들고 메소드를 3개로 나눠서 구현해줘도 되겠습니다.

 문제는 이렇게해서 생성 호출된 빈 액티비티는 종료를 해줘야하는데요, 종료 시점이

private void DuokuLoginRequest() { // 로그인 요청과 로그인 리스너 등록 DkPlatform.getInstance().dkLogin(this, new OnLoginProcessListener() { @Override p…

Eclipse An error has occurred. See the log file

이미지
이클립스 실행중 위와 같이 An error has occurred. See the log file ... workspace\.metadata\.log 에러가 발생했습니다. 로그를 보면,


!SESSION 2013-09-16 10:43:09.054 -----------------------------------------------
eclipse.buildId=v21.1.0-569685
java.version=1.7.0_05
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ko_KR
Framework arguments:  -product com.android.ide.eclipse.adt.package.product
Command-line arguments:  -os win32 -ws win32 -arch x86_64 -product com.android.ide.eclipse.adt.package.product

!ENTRY org.eclipse.osgi 4 0 2013-09-16 10:43:11.469
!MESSAGE An error occurred while automatically activating bundle org.eclipse.core.resources (81).
!STACK 0
org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources.
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleCont…

Unity3D iOS LitJson KeyNotFoundException: The given key was not present in the dictionary

KeyNotFoundException: The given key was not present in the dictionary.

at System.Collections.Generic.Dictionary`2[System.String,LitJson.JsonData].get_Item (System.String key) [0x00000] in <filename unknown>:0
at LitJson.JsonData.get_Item (System.String prop_name) [0x00000] in <filename unknown>:0
at iOSManager.ResultFriendsInfo (System.String jsonFriends) [0x00000] in <filename unknown>:0

(Filename: Line: -1)

 유니티3D iOS 플러그인 작업중 LitJson을 사용하는데 있어서 처음에는 잘되는데 2번째부터 위와 같은 오류가 발생했습니다. 안드로이드에서는 잘 되었는데 구글링을 해보니 다른 분들도 iOS에서 같은 오류가 발생하는 것 같더군요.

public void ResultFriendsInfo(string jsonFriends) { JsonReader reader = new JsonReader(jsonFriends); string strFacebookId = string.Empty; string strFacebookName = string.Empty; while(reader.Read()) { if(reader.Token.ToString() == "PropertyName" && reader.Value.ToString() == "FacebookId") { reader.Read(); strFacebookId = reader.Value.ToString(); } if(reader.Token.ToStr…

CocosBuilder 3.0 alpha5에서 리소스뷰와 프리뷰가 보이지 않는 버그

이미지
올해초 코코스빌더 2.0에서 3.0으로 마이그레이션 한 뒤로 오랜만에 코코스빌더를 만져보게 되었습니다.

 그런데 코코스빌더 3.0도 알파5까지 릴리즈 되면서 맥 OSX 10.7 에서는 위 그림과 같이 왼쪽의 리소스뷰와 프리뷰가 있는 프로젝트뷰가 보이지 않는 버그가 있더군요. 내부적으로 맥 OSX 10.8만 지원하는 API를 사용해 코코스빌더가 개발된 상태라 이런 이슈가 있다고 합니다.

코코스빌더 다운로드 페이지에가서 코코스빌더 3.0 알파 5 소스버전을 다운로드 후 압축해제하고 위 그림과 같이 코코스빌더 빌드를 위해 Scheme를 CocosBuilder로 변경하고 CocosBuilderAppDelegate.m 파일을 수정합니다.

 위와 같이 생긴 - (void) setupResourceManager 이라는 함수를 수정해줘야 하는데,

[[NSBundlemainBundle] loadNibNamed:@"ResourceManagerPreviewView"owner:previewViewOwnertopLevelObjects:&topLevelObjs];
 이부분을
NSNib *nib = [[NSNiballoc] initWithNibNamed:@"ResourceManagerPreviewView"bundle:[NSBundlemainBundle]]; if (![nib instantiateNibWithOwner:previewViewOwnertopLevelObjects:&topLevelObjs]) { return;     }     [nib release];     [topLevelObjs makeObjectsPerformSelector:@selector(release)];
 이렇게 수정 후 빌드해서 직접 사용하시면 됩니다.
 이제야 정상작동하고 있네요. 다음 정식 업데이트 버전등에선 수정이 되길 기대해봅니다.

Unity3D iOS용 JSON Lib SBJson for Objective-C

이미지
유니티3D 안드로이드 플러그인들 작업에이어 요즘은 iOS 플러그인 작업에 열중하고 있습니다. 그중에서 페이스북 연동하는데 있어 iOS딴 오브젝트-C용 JSON 라이브러리가 필요하게 되었습니다.

 리서치를 해보니 TouchJSON 이나 JSONKit 또는 SBJson등이 있더군요. 이번 포스팅에서는 이 JSON 라이브러리중에서 SBJson을 유니티3D에 적용해 보는것을 정리하겠습니다.

 물론 SBJson을 사용하지 않고 애플에서 iOS 5.x부터 추가한 NSJSONSerialization을 사용해도 되겠지만 5.x 이하의 iOS도 지원해주려면 이런 외부 라이브러리를 써야하는게 답인듯 합니다.


1. 설치
SBJson의 GitHub에가서 현재 최신 버전인 3.2.0을 다운로드 후 적절한 곳에 압축해제합니다.


2. 유니티3D iOS 플러그인 프로젝트에 SBJson 적용

 압축 해제후 모습입니다. 여기서 Classes안에 있는 SBJson h파일과 m 소스 파일들을 유니티3D iOS 플러그인 디렉터리에 복사합니다.

 파일을 복사했습니다. 이제 빌드해보면,

 이렇게 iOS 프로젝트의 Libraries 폴더에 SBJson의 소스파일이 프로젝트 네비게이터에 추가된 것을 확인할 수 있습니다. m 파일만 복사된 것 같지만,

  실제 폴더에는 h 파일도 복사되어 있습니다.

 유니티3D를 기반으로 설명하고 있지만 일반 iOS Xcode 프로젝트에서도 프로젝트 네비게이터에 SBJson 파일들을 추가해주시면 됩니다.

 이제 빌드를 해보면 Libraries/NSObject+SBJson.m:31:2: "This source file must be compiled with ARC enabled!" 에러가 발생할텐데요, 유니티3D가 자동 생성한 iOS 프로젝트는 ARC를 지원하지 않아서 생긴 에러입니다. 링크를 확인하시어 해결하시기 바랍니다.


- (void) requestFriendsInfo { if (FBSession.activeSession.isOpen) {         [[…

Unity3D iOS SBJson This source file must be compiled with ARC enabled

이미지
Libraries/NSObject+SBJson.m:31:2: "This source file must be compiled with ARC enabled!"

 iOS용 JSON lib인 SBJson을 프로젝트에 추가 후 빌드중 위와 같은 에러가 발생했습니다. ARC(Automatic Reference Counting)라고 애플에서 비교적 최근에 추가한 자동 레퍼런스 카운트 관련 기능이라고 하네요. 런타임에 해주는게 아니고 컴파일러가 컴파일딴에 자동으로 release 코드를 삽입시켜 준다고 합니다.

 자세한 내용은 위 링크를 참고하시고 SBJson은 빌드시 arc를 활성화 해줘야합니다. 유니티3D에서 자동 생성한 iOS xcode 프로젝트는 arc도 비활성화 되어있고 arc에 만족하는 소스 코드도 아니라서 Build Settings의 Objectivie-C Automatic Reference Counting 옵션을 Yes로 해서는 해결이 되지 않고 위 그림과 같이 Build Phases -> Compile Sources에서 SBJson관련 파일만 선택 후 더블클릭 또는 엔터키를 눌러 나온 팝업창에 -fobjc-arc 를 추가해줍니다.

 이렇게 말이죠. 그리고 빌드하면 이상없이 빌드가 완료됩니다.

Unity3D iOS에서 사운드가 나오지 않을때?

이미지
안드로이드에만 서비스하던 게임을 iOS도 요즘 준비중에 있습니다. 휴가 복귀 후 해결해야할 이슈가 하나가 생겼는데 안드로이드와 기타 PC에서는 유니티3D 배경음이나 효과음 같은 사운드들이 잘 재생이 되는데 유독 iOS에서만 볼륨을 최대로해도 사운드가 들리지 않는다는 것이었습니다.

 처음에는 위와 같은 3D Sound 관련 값들을 수정해 보거나 카메라의 위차가 잘 못 되었나 확인해봤지만 이상이 없었습니다. 구글링을 해봐도 카메라 위치나 3D 사운드 관련된 내용뿐이었죠.

 그런데 이어폰을 꽂아 들으니 사운드가 잘 나왔습니다. 이상하죠? 근데 문제의 원인은 엉뚱한 곳에 있었는데요, 바로

 아이패드 볼륨버튼 오른쪽에 있는 소리 뮤트 버튼이 원인이었습니다. 제가 휴가간 사이 이것때문에 고생하신 팀장님과 저도 몇년전 잠깐 아이팟터치 잠시 써본 것 말고는 써보지 않은 애플의 디바이스 특징을 모르다보니 소스딴 이슈거나 유니티3D 인스펙터 설정 이슈인가 했던게 아닌걸로 판정이 났네요 ㅎ;

 저처럼 아이폰 디바이스 특성을 모르는 분들이 혹 계실까봐 정리를 해봅니다. 아무튼 어제 한바탕 웃는 시간이 있었네요~

Unity3D Baidu Duoku 1.1.0 업데이트 작업 변경 사항

중국 마켓들이 자꾸 게임 출시전에 SDK를 업데이트하네요. 전에는 91SDK가 3.2.5로 업데이트 한걸 적용해 달라고 하더니 이번에는 바이두 Duoku SDK가 출시직전 업데이트 되서 왔네요.

DescriptionResourcePathLocationType
The method dkAppVersionUpdate(Activity, new DkProCallbackListener.OnAppVersionUpdateListener<Integer>(){}) is undefined for the type DkPlatformDuokuHandler.java/PluginChina91DKUC/src/com/kabod/DungeonBreaker/ucline 173Java Problem
The method dkUniPayForCoin(Activity, int, String, String, int, String, DkProCallbackListener.OnExitChargeCenterListener) in the type DkPlatform is not applicable for the arguments (Activity, String, String, String, String, String)DuokuHandler.java/PluginChina91DKUC/src/com/kabod/DungeonBreaker/ucline 166Java Problem
The method dkSetSessionInvalideListener(new DkProCallbackListener.OnSessionInvalidListener(){}) is undefined for the type DkPlatformDuokuHandler.java/PluginChina91DKUC/src/com/kabod/DungeonBreaker/ucline 243Java Problem
The method dkSetOnLoginPageDestroyedListener(new DkProCallbackListener.OnLogin…