[링크] InvalidOperationException: out of sync
[링크] http://specialmylife.tistory.com/entry/Dictionary-value-%EB%B3%80%EA%B2%BD
[링크2] https://westwoodforever.blogspot.kr/2013/07/c-invalidoperationexception-out-of-sync.html
[링크] http://specialmylife.tistory.com/entry/Dictionary-value-%EB%B3%80%EA%B2%BD
[링크2] https://westwoodforever.blogspot.kr/2013/07/c-invalidoperationexception-out-of-sync.html
[링크] 애플, macOS에서 확인되지 않은 개발자가 배포한 앱 실행하는 옵션 삭제... 우회로는 남겨놔 (0) | 2017.07.28 |
---|---|
[펌] Unity UnityException: Unable to install APK! (0) | 2017.07.26 |
[펌] CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct. (0) | 2017.06.07 |
[펌] Invalid Asset Bundle and downloading failed (connection refused) (0) | 2017.04.13 |
[에러] .ResolutionException: Cannot find candidate artifact for com.google.android.gms (0) | 2017.03.13 |
[출처] 게임코디 Rh님
[펌][SourceTree] 갑자기 실행이 안될때 (0) | 2017.10.23 |
---|---|
[링크] Pro Git[ebook] (0) | 2017.07.29 |
[Util] GitKraken (0) | 2017.06.29 |
Git: Rebase는 언제 어떻게 해야 할까? (0) | 2015.02.23 |
Git 도구 - 서브모듈 (0) | 2015.02.04 |
[링크] Pro Git[ebook] (0) | 2017.07.29 |
---|---|
[Bug] SourceTree for Mac (0) | 2017.06.29 |
Git: Rebase는 언제 어떻게 해야 할까? (0) | 2015.02.23 |
Git 도구 - 서브모듈 (0) | 2015.02.04 |
[수정] 윈도우의 SourceTree 및 TortoiseGit 에서 ssh password 요구하는 경우 해결방법 (0) | 2015.01.22 |
[링크]
[앱다운로드]
[링크] 자존감 있는 아이로 키우는 칭찬의 기술 (feat.책쟁이엄마) (0) | 2019.10.24 |
---|---|
[링크] 아이랑 잠깐만 있어도 왜 이렇게 피곤한 걸까요? (0) | 2019.08.12 |
[링크] 아이를 키운다면 반드시 봐야 할 감정코치 동영상 정리 (0) | 2019.06.04 |
[링크] 워킹맘, 완벽함보다 더 중요한 것 (0) | 2019.01.21 |
[추천APP] 베이비타임 BabyTime - 모유 수유, 수면 패턴 기록 앱 (0) | 2017.06.20 |
[링크] 자존감 있는 아이로 키우는 칭찬의 기술 (feat.책쟁이엄마) (0) | 2019.10.24 |
---|---|
[링크] 아이랑 잠깐만 있어도 왜 이렇게 피곤한 걸까요? (0) | 2019.08.12 |
[링크] 아이를 키운다면 반드시 봐야 할 감정코치 동영상 정리 (0) | 2019.06.04 |
[링크] 워킹맘, 완벽함보다 더 중요한 것 (0) | 2019.01.21 |
[추천APP] 차이의 놀이 (0) | 2017.06.20 |
AndroidManifest에 다음 줄을 추가하면
시작하자마자 뜨는 퍼미션 요청을 스킵할 수 있습니다.
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
출처: http://minhyeokism.tistory.com/54 [programmer-dominic.kim]
ARKit(Animoji 관련) (0) | 2017.09.26 |
---|---|
[링크] 구글 플레이 스토어 오류 해결 마법사 (0) | 2017.07.20 |
[펌] 유니티(Unity) 엔진 사용 시 모바일 기기의 화면 잠금을 막는 방법 (0) | 2017.06.13 |
[링크] 유니티(UNITY) / 모바일 터치 코드 요약 (0) | 2017.05.31 |
[링크] 유니티 2D 모바일 게임 빌드 최적화 팁 (0) | 2017.05.12 |
우선, 유니티에서 Window -> Services 합니다.
그러고 나면 Inspector 옆에 Services라는 텝이 생기는데
Select Organization 하고 Create 해줍니다.
그러면 유니티에서 제공하는 Service들이 보일 것입니다.
그 중에, OFF상태인 In-App Purchasing 텝을 클릭합니다.
우측상단에 있는 토글을 눌러 OFF되어있던 상태를 ON으로 만들어줍니다.
그리고 13세 이하 어린이에게 지도감독이 필요한 지 여부를 선택하고 Save Changes 합니다.
이제, 프로젝트에 In-App Purchasing이 활성화 된 모습을 보실 수 있을 것입니다.
여기서 잊지말고 Import 버튼을 꼬옥 눌러줍니다!
프로젝트 뷰에 Unity IAP 플러그인이 제대로 임포트 된 모습입니다.
이제 기본 세팅이 다 되었습니다. 그렇다면 코딩을 해볼까요?
아래와 같이 Script를 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | using System; using UnityEngine; using UnityEngine.Purchasing; public class InAppPurchaser : MonoBehaviour, IStoreListener { private static IStoreController storeController; private static IExtensionProvider extensionProvider; #region 상품ID // 상품ID는 구글 개발자 콘솔에 등록한 상품ID와 동일하게 해주세요. public const string productId1 = "gem1"; public const string productId2 = "gem2"; public const string productId3 = "gem3"; public const string productId4 = "gem4"; public const string productId5 = "gem5"; #endregion void Start() { InitializePurchasing(); } private bool IsInitialized() { return (storeController != null && extensionProvider != null); } public void InitializePurchasing() { if (IsInitialized()) return; var module = StandardPurchasingModule.Instance(); ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); builder.AddProduct(productId1, ProductType.Consumable, new IDs { { productId1, AppleAppStore.Name }, { productId1, GooglePlay.Name }, }); builder.AddProduct(productId2, ProductType.Consumable, new IDs { { productId2, AppleAppStore.Name }, { productId2, GooglePlay.Name }, } ); builder.AddProduct(productId3, ProductType.Consumable, new IDs { { productId3, AppleAppStore.Name }, { productId3, GooglePlay.Name }, }); builder.AddProduct(productId4, ProductType.Consumable, new IDs { { productId4, AppleAppStore.Name }, { productId4, GooglePlay.Name }, }); builder.AddProduct(productId5, ProductType.Consumable, new IDs { { productId5, AppleAppStore.Name }, { productId5, GooglePlay.Name }, }); UnityPurchasing.Initialize(this, builder); } public void BuyProductID(string productId) { try { if (IsInitialized()) { Product p = storeController.products.WithID(productId); if (p != null && p.availableToPurchase) { Debug.Log(string.Format("Purchasing product asychronously: '{0}'", p.definition.id)); storeController.InitiatePurchase(p); } else { Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); } } else { Debug.Log("BuyProductID FAIL. Not initialized."); } } catch (Exception e) { Debug.Log("BuyProductID: FAIL. Exception during purchase. " + e); } } public void RestorePurchase() { if (!IsInitialized()) { Debug.Log("RestorePurchases FAIL. Not initialized."); return; } if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.OSXPlayer) { Debug.Log("RestorePurchases started ..."); var apple = extensionProvider.GetExtension<IAppleExtensions>(); apple.RestoreTransactions ( (result) => { Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore."); } ); } else { Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform); } } public void OnInitialized(IStoreController sc, IExtensionProvider ep) { Debug.Log("OnInitialized : PASS"); storeController = sc; extensionProvider = ep; } public void OnInitializeFailed(InitializationFailureReason reason) { Debug.Log("OnInitializeFailed InitializationFailureReason:" + reason); } public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id)); switch (args.purchasedProduct.definition.id) { case productId1: // ex) gem 10개 지급 break; case productId2: // ex) gem 50개 지급 break; case productId3: // ex) gem 100개 지급 break; case productId4: // ex) gem 300개 지급 break; case productId5: // ex) gem 500개 지급 break; } return PurchaseProcessingResult.Complete; } public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason)); } } | cs |
결제를 진행해야하는 부분에서
위의 BuyProductID 함수의 파라미터로 상품ID를 넣고 콜(구매요청)하면
product가 initialize된 후 ProcessPurchase로 결과가 넘어오는데
args.purchasedProduct.definition.id로 구매요청된 상품ID를 판별하여
상품에 맞는 보상을 지급해주면 됩니다. 참 쉽죠?
유니티 5.3버전 이전에는(유니티가 자체 IAP를 지원하기 전) Android와 iOS 각각 따로 결제시스템을 만들어야했는데
지금은 Android와 iOS를 동시에 지원해주기 때문에 정말 편하답니다~
결제된 정보는 구글 Payments 판매자 센터에서 확인하실 수 있습니다. (https://wallet.google.com/merchant)
출처: http://minhyeokism.tistory.com/47 [programmer-dominic.kim]
유니티 엔진 사용 시 입력을 하지 않으면 모바일 장치의 화면이 어두워지다가 잠기게 되는데, 그러면 플레이어는 잠김을 다시 풀어야 해서 불편합니다. 따라서 화면 잠금 방지 기능 추가는 필수적이고, Screen.sleepTimeout를 아래처럼 설정하면 그걸 할 수 있습니다.
1 | Screen.sleepTimeout = SleepTimeout.NeverSleep; |
참고:
[링크] 구글 플레이 스토어 오류 해결 마법사 (0) | 2017.07.20 |
---|---|
[Unity3D] 안드로이드 App 실행 후 퍼미션 요청 스킵하는 방법 (SkipPermissionsDialog) (0) | 2017.06.19 |
[링크] 유니티(UNITY) / 모바일 터치 코드 요약 (0) | 2017.05.31 |
[링크] 유니티 2D 모바일 게임 빌드 최적화 팁 (0) | 2017.05.12 |
[링크] ETC1 + Alpha (0) | 2017.04.06 |
저도 동일한 문제로 헤매다가
http://answers.unity3d.com/questions/1320150/unable-to-list-target-platform.html
참고하여 해결했습니다.
위 링크 들어가 보시면 댓글에 해결책이 있는데
여기에 요약하면
Android SDK tools 가 최신 버전(25.3.1)으로 업데이트 되면서 unity가 사용하던 기능이 없어진거 같다고 합니다.
해결책은 기존 Android SDK설치 폴더에서 tools 폴더 이름을 변경한 후 [Your Android SDK root]/tools -> toolsXXXX
http://dl-ssl.google.com/android/repository/tools_r25.2.5-windows.zip 를 다운로드 받아서 압축 풀고 해당 tools 폴더를 위의
Android SDK설치 폴더에 복사합니다. 그러면 unity에서 예전처럼 잘 됩니다.
[출처] http://devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=79671&&#c_81343
[참조] http://answers.unity3d.com/questions/1320150/unable-to-list-target-platform.html
[펌] Unity UnityException: Unable to install APK! (0) | 2017.07.26 |
---|---|
[링크] InvalidOperationException: out of sync (0) | 2017.07.11 |
[펌] Invalid Asset Bundle and downloading failed (connection refused) (0) | 2017.04.13 |
[에러] .ResolutionException: Cannot find candidate artifact for com.google.android.gms (0) | 2017.03.13 |
[펌][APK] "패키지 파일이 올바르지 않습니다." 라는 오류 메시지와 함께 설치가 되지 않아요. (0) | 2017.02.14 |
NGUI 를 사용하면서 일반 오브젝트와 UI 오브젝트의 입력(터치)을 어떻게 처리해야 할지 알아본다.
일단, 보통은 게임에서 사용하는 Main Camera와 NGUI > Create UI 를 통해 생성되는 2D Camera(UI Camera) 두개(혹은 그 이상)를 사용할 것이다.
당연히 UICamera에 추가되는 Widget들은 UICamera 의 통제에 의해 OnHover, OnClick 등의 이벤트를 받는다.
하지만 게임오브젝트를 선택하려면? 당신은 여러가지의 고민을 하게된다.
'UI의 이벤트를 받지 않으려면?', '혹은 UI를 클릭했을때 게임오브젝트의 클릭을 무시하려면?' 등등...
하여, 이를 해결하기 위해 Picking Manager 라던지 NGUI의 메시지를 무시하는 플래그를 작성하던지의 시도를 해볼것이다.
NGUI는 이 상황에 대해 다음을 권고한다.
'모든 카메라에 UICamera 컴포넌트를 추가하세요!'
일단 NGUI:UICamera 의 내용을 보면, UI카메라에 추가되었을경우엔 UI 들에게, Main Camera에 추가하면 인게임 오브젝트들에게 특정 이벤트 메시지를 보낸다고 써져있다. 본문
이벤트는 다음 링크를 참고한다. 이벤트
실제로 테스트 해본 결과,
1. 같은 레이어상의 UI와 non-UI 오브젝트(in-game object)로 테스트 시.
2개의 카메라(Main-Camera, UI-Camera)에 각각 UICamera 컴포넌트를 포함시킨후 실험.
NGUI Widget 툴을 통해 UI-Camera에 바탕 윈도우와 버튼을 하나 추가했다.
테스트를 위해 2개의 큐브를 씬에 추가. 스크립트를 작성하되, void OnClick() 함수를 추가했다.
테스트 결과, 버튼 영역을 클릭했을때, UIButton만 동작되었다.
게임 오브젝트 클릭시 OnClick이벤트가 정상 동작되었으며, 깊이에 따라 먼저 클릭된 게임오브젝트만 동작되었다.
버튼 영역을 제외한 UI윈도우 영역은 클릭테스트에 제외되며, 게임 오브젝트가 하단에 존재하면 게임오브젝트 이벤트가 호출된다.
- UI윈도우도 클릭테스트에 포함시키기 위해서는 Add Component > Physics > Box Collider 를 추가해준다. 추가후에는 윈도우에서 이벤트를 처리하기 때문에 윈도우 영역 클릭시 게임 오브젝트는 이벤트를 받지 않는다.
- 버튼이 isEnable=false; 되어있다면, 이벤트를 받지 않는다.
2. UI 부분을 다른 레이어로 세팅.
- 동일한 레이어일때와 결과가 같다.
즉, 이왕 NGUI를 사용한다면, 모든 카메라에 UICamera 컴포넌트를 추가하고, 입력이 필요한 오브젝트 마다 이벤트 함수를 추가해주자.
출처: http://toymaker.tistory.com/entry/NGUI-UI와-일반-오브젝트의-터치-이벤트-처리 [ToyMaker]
[펌] NGUI 최적화의 핵심 (0) | 2017.10.11 |
---|---|
[펌] NGUI의 UILabel에서 개행(\n)이 안되는 문제 (0) | 2017.07.17 |
[펌] Blur filter for UITexture in NGUI (0) | 2017.02.09 |
[펌] NGUI 쉽게 말풍선 만들기 (0) | 2017.02.03 |
[링크] InfiniteList_NGUI (0) | 2016.10.27 |