8월, 2013의 게시물 표시

Unity3D iOS RootViewController 가져오기

이미지
Cannot initialize a parameter of type 'UIViewController *' with an lvalue of type 'iOSFacebookPlugin *'

 유니티3D iOS 페이스북 연동 중 위와 같이 에러가 발생했습니다.

 RootViewController이 필요한데 유니티 iOS 프로젝트를 빌드하면 자동으로 생성되는 파일중 iPhone_View.h 와 mm에 위 그림과 같이 구현이 되어있습니다.


externUIViewController* UnityGetGLViewController();

UIViewController* pRootViewController = UnityGetGLViewController();
 사용하는 부분에서 위와 같이 가져오면 됩니다. 일반적인 iOS 개발이나 cocos2d-x 기반에서 RootViewController을 가져오는 것보다 쉽네요.

facebook iOS Cannot use the Facebook app or Safari to authorize, is not registered as a URL Scheme

이미지
Cannot use the Facebook app or Safari to authorize, is not registered as a URL Scheme

 유니티3D iOS에 페이스북 연동중 위와 같은 에러가 발생했습니다.

 iOS 플러그인 프로젝트의 info.plist에 그림과 같이 URL types를 추가해서 Item 0 - URL Schemes - Item 0 에 fb + 페이스북 App ID 를 입력해줍니다. + 는 당연히 빼주시고요.

 예전에 iOS에서 URL로 웹 링크 호출하는 것을 정리했었는데 지금 정리한 URL Schemes는 반대로 호출 된 웹에서 다시 앱을 호출하는 것을 처리하기 위해 필요한 듯 하네요.

Apple URL Scheme Reference

Unity3D Google APK Expansion Files 연동 2. OBB 업로드 및 다운로드 그리고 적용

이미지
지난 포스팅에서 유니티3D에 구글 APK Expansion Files 연동을 위해 유니티사에서 만든 Google Play OBB Downloader 플러그인 설치 및 에셋 번들을 이용한 OBB 파일 생성까지 정리해 봤습니다. 이번 포스팅은 만들어진 OBB를 적용하기 위한 과정으로 구글 플레이에 APK와 함께 OBB 파일을 업로드하는 과정과 OBB 다운로더를 통해 다운로드한 OBB를 가져와 사용해 보는 것을 정리해 봅니다.


1. 구글 플레이에 OBB 업로드

구글 플레이 개발자 콘솔에 새 애플리케이션을 추가합니다. 저는 OBBTest라고 했습니다. 링크의 내용은 비교적 예전 내용이라 현 구글 플레이와 다르겠지만 참고할만 합니다.

 구글 플레이 콘솔이 많이 바겼네요. 일단 테스트 앱이라 알파 테스트에 APK를 업로드 진행 했습니다.

 APK를 올린 후 결과 화면에서 위와같이 확장 파일 사용이라는 메뉴가 있습니다. 처음이라 확장 파일이 없음이라고 나오죠. 새 파일 업로드를 클릭해서 만들었던 OBBTest.zip 파일을 업로드 합니다.

 그리고 며칠전 작업 내용이라 에매한 부분이 있는데 첫 APK를 올렸을 때 저 확장 파일 사용 메뉴는 볼 수 없었고 처음 올린 후 다시 '알파로 새 APK 업로드' 버튼을 눌러 같은 버젼을 올리고 나서야 확장 파일을 올릴 수 있던걸로 기억이 나네요.

 OBBTest.zip 파일이 업로드 됩니다.

 OBBTest.zip 이었는데 올린 후에 자동으로 main.8.com.wwforever.obbtest.obbOBBTest.main.obb로 올라갑니다. obb로 올라가는 규칙은 main 또는 patch.Bundle Version Code.Bundle IDentifier.obb 로 알아서 올라가는거죠. 이런 규칙은 밑에서 나올 GooglePlayDownloader.cs 파일을 분석해 보면 더 자세히 알 수 있습니다.

 이런식으로 obb는 APK 업로드할 때 같이 올려주면 됩니다.


2. OBB 다운로드 및 적용

static Google…

facebook Assigning to 'FBRequestConnectionErrorBehavior' from incompatible type 'int'

이미지
Assigning to 'FBRequestConnectionErrorBehavior' from incompatible type 'int'

 유니티3D iOS에 페이스북 연동 플러그인 작업중 위와 같은 오류가 발생했습니다.

 이상합니다. 페이스북의 HelloFacebookSample에 있는 Post 하는 부분 소스를 그대로 가져왔던건데 샘플에서는 빌드가 잘 되더군요.

connection.errorBehavior = (FBRequestConnectionErrorBehavior)(FBRequestConnectionErrorBehaviorReconnectSession                 | FBRequestConnectionErrorBehaviorAlertUser
                | FBRequestConnectionErrorBehaviorRetry);
 일단 간단하게 형변환을 해줘서 해결했습니다.

Unity3D Google APK Expansion Files 연동 1. 준비작업

이미지
유니티3D 에셋번들을 활용해서 버전 관리까지하는 패치 시스템을 만들어 사용중에 있습니다. 그런데 태국에서 자체 패치 말고 구글의 APK Expansion Files(이하 OBB)을 사용해 달라는 요구사항이 있어서 이번 포스팅에서는 OBB를 사용하기 위한 준비 작업을 정리하겠습니다.

 에셋 번들을 이용한 패치 시스템은 APK만 받고 나머지는 그때그때 업데이트시마다 받으면 되는데 반해 OBB는 APK 업데이트하면 관련 OBB도 업데이트하는등 더 비효율적으로 보이는데 왜 이걸로 하는지 모르겠네요. 물론 개발사측에서는 추가 패치 서버를 준비 안해도 되는 이점은 있습니다.


1. Google Play OBB Downloader 플러그인 설치

 먼저 간단한 유니티3D 프로젝트를 만들고 구글 플레이 OBB 다운로더를 다운로드 해줍니다. 유니티3D가 아니고 일반 안드로이드 작업이었다면 안드로이드 SDK 메니저에서 Google Play APK Expansion Library와 Google Play Licensing Library를 추가로 설치하는 등의 작업이 필요하지만 다행스럽게도 유니티사에서 만든 플러그인이 있네요.

 제 경우 플러그인 설치는 처음이라 위 그림과 같은 외부 프로토콜 요청 창이 뜨는데 외부에서 유니티3D를 실행하기 위한 단계로 체크박스를 체크 후 애플리케이션 시작을 클릭합니다.

 유니티3D가 실행이 되고 에셋 스토어가 실행이 됩니다. 조금 전에 웹에서 보던 것과 비슷한 모습인데요, Download를 클릭해 Google Play OBB Downloader를 다운로드 합니다.

 이제 프로젝트에 모두 임포트합니다.

 임포트하면 Plugins/Android에 관련 파일들이 생깁니다. 나중에 GooglePlayDownloader.cs 파일에 앱의 공개키를 설정합니다.

 또한 Assets 루트 폴더에는 샘플 소스인 DownloadObbExample.cs라는 파일이 생깁니다.


2. APK 빌드하기

 OBB파일을 생성하기 위해 Android Player Settings ->…

cocos2d-x /usr/bin/evn: bad interpreter: No such file or directory

이미지
cocos2d-x 3.0 alpha를 본격적으로 사용 해보려고 합니다. 2.1.2에서 생겼던 멀티 플랫폼 프로젝트 생성기인 project-creator를 사용해서 3.0용 프로젝트를 만들어 봤습니다.

 일단 2.1.2와는 다르게 create-multi-platform-projects.py 라고 cocos2d-x 루트에 있고 옵션도 -p와 -k, -l로 짧아졌네요. 문제는 그게 아니고

-bash: ./create-multi-platform-projects.py: /usr/bin/evn: bad interpreter: No such file or directory

 이런 에러가 발생하면서 생성이 안 된다는거죠. 검색해보면 vi 에디터로 확인시 이상한 개행문자가 포함되서 발생하는 에러도 있다지만 그런 경우는 아니었습니다.

#! /usr/bin/evn python
# filename = create-multi-platform-projects.py

import os
from tools.project_creator import create_project

if __name__ == '__main__':
    os.chdir(os.getcwd()+'/tools/project_creator/')
    create_project.createPlatformProjects()

 내용은 이리 간단한데 말이죠. 그냥 tools/project_creator/에 있는 create_project.py의 createPlatformProjects를 호출하는게 다죠.

 아직은 3.0 알파버전이라 문제가 있는거겠죠. 일단 2.1.2에서 했던데로 직접 tools/project_creator로 이동후

./create_project.py -p testgame -k com.wwforever.game -l cpp

 위와 같은 옵션으로 실행해서 프로젝트를 생성할 수 있습니다. -p는 프로젝트명 -k는 패키지명 -l은 개발 언어입니다.

Unity3D iOS referenced from: __Z19RegisterMonoModulesv in RegisterMonoModules.o

이미지
Undefined symbols for architecture armv7:   "_iOSPluginHelloWorld", referenced from:       __Z19RegisterMonoModulesv in RegisterMonoModules.o ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
 유니티3D iOS 플러그인을 만들던 중 위와 같이 에러가 발생했습니다.


[DllImport("__Internal")] privatestaticexternvoid iOSPluginHelloWorld(string strMessage);
 유니티3D에서 위와같이 iOS 네이티브 코드를 호출하기 위해 extern 메서드를 선언해줘야하죠.

 그러면 빌드 후 자동으로 생성되는 Libraries/Assembly-CSharp.dll.s 과 RegisterMonoModules.cpp에 위 그림과 같이 해당 정보가 포함됩니다.

void iOSPluginHelloWorld(constchar* strMessage) { NSLog(@"iOS Log 1"); UnitySendMessage("iOSManager", "SetLog", strMessage); NSLog(@"iOS Log 2");
}
 해결하려면 함수 정의를 해줘야합니다. Classes 폴더에 원하시는 m 파일을 하나 만들어 위와 같이 함수 본체를 정의하거나

extern"C" { void iOSPluginHelloWorld(constchar* strMessage) {     //NSLog(@"iOS Log 1");     UnitySendMessage("iOSManager", "SetLog&q…

iOS could not change executable permissions on the application

이미지
오랜만에 iOS 관련 작업중에 위 그림과 같은 에러가 발생했습니다. 원인은 Bundle Identifier가 같은 앱이 디바이스에 설치 되어 있을 때 발생하는 것으로 기존 앱을 삭제 후 진행하면 됩니다. 예전에 cocos2d-x 기반 프로젝트 할 때는 안 이랬던것 같은데 그동안 iOS SDK 버전 올라가면서 바겼나보네요.

Unity3D 커스텀 클래스를 인스펙터와 연결하기

이미지
유니티3D에서 MonoBehaviour을 상속하지 않는 유저 커스텀 클래스를 인스펙터와 연결하여 표출하려면 기존의 javascript와는 다르게 C#은 추가 작업이 필요하네요.


[System.Serializable] public class SpriteManager { public Texture2D spriteTexture; public int in_framePerSec; public int in_gridX; public int in_gridY; }  익스펙터와 연결하기 위한 클래스 위에 [Serializable] 속성을 추가해주면 해당 클래스의 public 멤버 변수가 노출이 됩니다.

error CS0052: Inconsistent accessibility: field type

error CS0052: Inconsistent accessibility: field type `xxx[]' is less accessible than field `yyy.zzz'

 해당 C# 컴파일 오류는 오류가 발생하는 xxx 클래스를 만들 때 public 구문을 추가해서 정의하면 됩니다. 즉, class xxx {} 가 아닌 public class xxx {} 이런식으로 말이죠.

msdn 컴파일러 오류 CS0052

Unity3D Asset bundles can not include Scenes

Asset bundles can not include Scenes: Assets/Scene/game.unity
If you want to stream a Scene, use BuildPipeline.BuildPlayer with BuildOptions.BuildAdditionalStreamedScenes.
UnityEditor.BuildPipeline:BuildAssetBundle(Object, Object[], String, BuildAssetBundleOptions, BuildTarget)
ExportAssetBundles:ExportResource() (at Assets/Editor/ExportAssetBundles.cs:14)

 씬을 에셋 번들로 만들려고 하니 위와같은 에러가 발생하네요. 씬은 기존에 리소스들을 에셋번들로 만들 때 사용하던 BuildPipeline.BuildAssetBundle로는 안되고 BuildPipeline.BuildStreamedSceneAssetBundle을 사용해야 하네요.

[MenuItem("Assets/Build Streamed Scenes")] static void BuildScenes() { string[] levels = {"Assets/Scene/game.unity", "Assets/Scene/setting.unity",}; BuildPipeline.BuildStreamedSceneAssetBundle(levels, path, BuildTarget.Android); }
 또는 BuildPipeline.BuildPlayer를 사용한다면 BuildOptions.BuildAdditionalStreamedScenes 옵션을 주고 만들면 됩니다.

Unity3D Integration MobileCharging TrueDigitalPlus

이미지
이번 포스팅은 중국에 이어 태국의 최대 통신사인지 방송사인지 암튼 True 그룹의 계열사인 트루 디지털 플러스(True Digital Plus)와 유니티3D 연동을 정리 해보겠습니다. 트루와 연동은 웹이 주된 작업이라 안드로이드 플러그인 작업은 없습니다. 첫번째로 모바일 충전 처리에 대한 내용입니다.


1. 트루 모바일 충전 요청

 먼저 유니티3D에서 트루에 POST로 충전 요청하는 내용입니다.

public class TrueManager : MonoBehaviour
{
static TrueManager _instance;
public string strLogMsg = "Unity3D Android True Digital Plus Test";
private string AppID = "1";
        private string SecretKey = "ababababababababababababababab";

public static TrueManager GetInstance()
{
if( _instance == null )
{
_instance = new GameObject("TrueManager").AddComponent<TrueManager>();
}

return _instance;
}
}
 먼저 TrueManager 컴포넌트 기본부분입니다. <> 때문에 신텍스하이라이터 오류가 발생해서 따로 빼봤습니다. AppID와 SecretKey는 트루로부터 할당 받습니다.
public void RequestCharging(int amount) { string TDP_URL = "http://smart.gg.in.th/MobileCharging/ProfileAuthen.aspx"; string EncryptSecret = Md5Sum(AppID+SecretKey); string DeviceID = SystemInfo.deviceUniqueIdentifier…

Unity3D ERROR: Unable to read 'D:\xxx.keystore' (details: Keystore was tampered with, or password was incorrect)

Error building Player: Exception: apk (invokation failed)
ERROR: Unable to read 'D:\unity3dandroidkey.keystore' (details: Keystore was tampered with, or password was incorrect)
cmd:apk D:\ProgramSource\OBBTest\UnityOBBTest\Temp/StagingArea/Package_unaligned.apk -z D:\ProgramSource\OBBTest\UnityOBBTest\Temp/StagingArea/assets.ap_ -z D:\ProgramSource\OBBTest\UnityOBBTest\Temp/StagingArea/bin/resources.ap_ -nf D:\ProgramSource\OBBTest\UnityOBBTest\Temp/StagingArea/libs -f D:\ProgramSource\OBBTest\UnityOBBTest\Temp/StagingArea/bin/classes.dex -v -k D:/unity3dandroidkey.keystore -kp wwforever -kk wwforeverkey -kkp wwforever
stdout;
stderr:
ERROR: Unable to read 'D:\unity3dandroidkey.keystore' (details: Keystore was tampered with, or password was incorrect)

 기존에 Keystore 패스워드를 입력하지 않은 에러와 비슷한데요, 패스워드가 잘 못 입력되면 위와같은 에러가 발생합니다.

Unity3D Error building Player: UnityException: Can not sign application

이미지
Error building Player: UnityException: Can not sign application
Unable to sign application; please provide passwords!

유니티3D에서 생성했던 안드로이드 Keystore의 패스워드를 입력하지 않아 발생했던 에러입니다. 패스워드 기입 후 다시 빌드를 시도하면 됩니다.

APK Expansion Files OBB 파일 다운 중 Download failed because the resources could not be found

이미지
I/Unity(770): /mnt/sdcard/Android/obb/com.wwforever.obbtest
I/Unity(770):
I/Unity(770): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngineDebug.cpp Line: 54)
I/ActivityManager(147): START {flg=0x10000 cmp=com.wwforever.obbtest/com.unity3d.plugin.downloader.UnityDownloaderActivity (has extras)} from pid 770
W/ActivityManager(147): Activity pause timeout for ActivityRecord{41776e20 com.wwforever.obbtest/com.unity3d.player.UnityPlayerNativeActivity}
D/Unity(770): onDetachedFromWindow
D/LVLDL(770): Service Bound
D/CancellableIntentService(770): stopSelf
D/CancellableIntentService(770): afterStopSelf
I/LicenseChecker(770): Binding to licensing service.
D/CancellableIntentService(770): onDestroy
I/ActivityManager(147): Displayed com.wwforever.obbtest/com.unity3d.plugin.downloader.UnityDownloaderActivity: +852ms
I/LicenseChecker(770): Calling checkLicense on service for com.wwforever.obbtest
I/LicenseChecker(770): Start monitoring timeout.
W/NetworkManagementSocketTagger(30676…

Unity3D 안드로이드 Keystore 생성하기

이미지
기존에 이클립스에서 Export Android Application을 하면서 만들었던 Keystore가 아닌 유니티3D에서 안드로이드 Keystore 만드는 것을 정리해봅니다. 유니티3D 툴 안에서 만들기 때문에 더 직관적입니다.

 안드로이드 Build Settings -> Publishing Settings의 Keystore부분에 그림과 같이 Create New Keystore를 체크하고 Browse Keystore를 클릭해 저장할 위치와 파일명을 설정합니다. 패스워드를 설정하고 Unsigned(debug) 콤보 박스를 클릭해보면 그전에는 없던 Create a new key가 생겨 있는데 클릭해서 Keystore 생성을 진행합니다.

 이클립스에서 생성하는 것과 비슷한 생성창이 뜹니다. Alias에는 별칭과 기존에 설정한 패스워드를 기입합니다. 또한 Validity(years)에 인증 유효기간을 기입하고 그 밑에는 생략가능하니 기입하고 싶은것을 기입 후 Create Key를 클릭합니다.

 원하는 위치에 지정한 이름으로 keystore가 생성이 된 것을 확인합니다.

 이제 Use Existing Keystore에 체크하고 만들어진 키스토어를 선택 후 패스워드를 입력해서 사용하면 됩니다.

Google APK Expansion Files 빌드중 cannot be resolved to a type

이미지
DescriptionResourcePathLocationType
LicenseChecker cannot be resolved to a typeDownloaderService.java/downloader_library/src/com/google/android/vending/expansion/downloader/implline 765Java Problem
LicenseChecker cannot be resolved to a typeDownloaderService.java/downloader_library/src/com/google/android/vending/expansion/downloader/implline 765Java Problem
LicenseCheckerCallback cannot be resolved to a typeDownloaderService.java/downloader_library/src/com/google/android/vending/expansion/downloader/implline 768Java Problem
The method allow(int) of type new LicenseCheckerCallback(){} must override or implement a supertype methodDownloaderService.java/downloader_library/src/com/google/android/vending/expansion/downloader/implline 771Java Problem
The method dontAllow(int) of type new LicenseCheckerCallback(){} must override or implement a supertype methodDownloaderService.java/downloader_library/src/com/google/android/vending/expansion/downloader/implline 863Java Problem
Policy cannot …

Unity3D 중국 마켓 SDK 4개 통합중 already added: Landroid/net/http/SslError

이미지
Error building Player: Exception: dx (invokation failed)
ERROR: unknown error
cmd:dx --dex --verbose --output=bin/classes.dex bin/classes.jar plugins
stdout;
processing archive bin\classes.jar...
processing com/unity3d/player/a$1.class...
...
processing archive plugins\.\alipay_msp.jar...
ignored resource META-INF/MANIFEST.MF
processing com/alipay/android/app/IRemoteServiceCallback$Stub$Proxy.class...
...
processing archive plugins\.\android-support-v4.jar...
ignored resource META-INF/MANIFEST.MF
processing android/support/v4/widget/CursorAdapter$1.class...
...
processing archive plugins\.\android_api.jar...
ignored resource META-INF/MANIFEST.MF
processing com/baidu/mobstat/a.class...
...
processing archive plugins\.\DkPlatformSdk.jar...
ignored resource META-INF/MANIFEST.MF
processing com/duoku/platform/DkErrorCode.class...
...
processing archive plugins\.\KabodChinaPlugins.jar...
ignored resource META-INF/MANIFEST.MF
processing com/kabod/pluginchina91dkuc/GameNollHandler.class...
.…

Unity3D 안드로이드 플러그인 JAR 파일 프로가드로 난독화하기

이미지
일반 안드로이드 어플에 사용하는 JAR 파일을 프로가드로 난독화 적용을 해봤었습니다. 이번에는 유니티3D 안드로이드 플러인에 난독화를 위한 프로가드 적용해보는 것을 정리하겠습니다. 지난번에 정리했던 중국 바이두의 Duoku 플랫폼 SDK 플러그인을 베이스로 정리합니다. 나머지 91 플랫폼 SDK, GameNoll, UCGame 플러그인들도 같은 방법으로 진행하면됩니다.

 그리고 아래의 내용은 안드로이드 JAR 플러그인을 만들어 유니티3D에서 빌드되는 환경을 위한 방식입니다. 그래서 플러그인 JAR 파일만 프로가드를 적용하고 있는 것이고요. 이클립스가 갑이되어 유니티3D 안드로이드 프로젝트를 빌드하는 환경에서는 아마도 UnityPlayerActivity 관련 프로가드 이슈가 있을 듯 하네요.

 지난번 안드로이드 JAR를 프로가드 적용했던 pro 설정파일을 기반으로 진행합니다. 해당 파일을 로딩 후 그림과 같이 기존 내용을 편집해줍니다. 특히 밑에 Library 부분은 기존보다 2개의 파일을 더 추가해야합니다. 유니티3D 관련 작업인만큼 classes.jar 파일과 바이두 Duoku SDK JAR 파일인 DkPlatformSdk.jar를 추가해줍니다. 추가하지 않으면 can't find superclass or interface 에러가 발생합니다.

-libraryjars 'C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\androidplayer\bin\classes.jar'
-libraryjars UnityDuokuTest\Assets\Plugins\Android\DkPlatformSdk.jar

 직접 수정시엔 위와 같습니다.

 더 진행하기에 앞서 유니티3D와 안드로이드가 통신하는 부분 즉 JNI 관련된 자바 소스 부분은 난독화에서 제외시켜줘야 합니다. 왜냐면 C#쪽의 JNI 호출 부분 스트링은 난독화가 적용이 안되기 때문인거죠.

! getMethodID("DuokuInit_U&…