728x90

문제: 유니티에서 실행하면 결제팝업이 뜨는데 핸드폰으로 안뜨는 이유

해결
- 구글은 직접 유니티에 붙어서 빌드해서 테스트 하면 안된다. 구글스토어에 내부테스트로 다운받아서 해야함.
- 내부 테스트에 올려서 구글플레이 스토어에서 다운받았는데도 안되는 경우 와이파이 연결이 되어 있는지 확인하기.
    와이파이를 끄니까 팝업이 뜬다.
- 빌링 퍼미션이 제대로 들어가 있는지 확인하기. gpt는 세가지를 알려줘서

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.android.vending.BILLING" />
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />

이렇게 넣었는데, 다른 사람들은 BILLING만 넣는것 같다. 빌링만 넣어도 무방한지는 다음에 테스트 해봐야겠다.

728x90
반응형
728x90

문제: 인앱결제 상품등록창이 안나오고, 인앱 상품을 추가하려면 결제 권한을 APK에 추가해야 합니다. 라고만 뜸.

해결: 결제 권한을 주어야 한다.

방법
1. Assets > Plugins > Android > AndroiManifest.xml에 
 </uses-permission android:name="com.android.vending.billing"> 를 추가해준다.

2. 다시 빌드해서 테스트앱에 배포하게 되면, 구글콘솔 화면이 바뀐다.

 

---------

* 만약 AndroiManifest.xml파일이 없다면, 

Edit > project settings > android 탭 > Publishing Settings > Build > Custom Main Manifest 체크하기.

728x90
반응형
728x90

CommandInvokationFailure: Gradle build failed. 
D:/Unity/UnityEditor/2019.4.1f1/Editor/Data/PlaybackEngines/AndroidPlayer\OpenJDK/bin\java.exe -classpath "D:\Unity\UnityEditor\2019.4.1f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-5.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "bundleRelease"

stderr[
error processing C:\Users\Shinirom\.gradle\caches\transforms-2\files-2.1\583a75497389cd684886f6ff612791df\jars\classes.jar


대강 이런 에러가 났다.

 

mainTemplate.gradle 파일이 

이런식으로 되어 있었다.

 

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN

apply plugin: 'com.android.library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // Add additional dependencies here if needed
}

android {
    compileSdkVersion 30
    buildToolsVersion '30.0.3'

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        minSdkVersion 30
        targetSdkVersion 32
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
        versionCode 1
        versionName '1.0'
        consumerProguardFiles 'proguard-unity.txt'
        multiDexEnabled true
    }
    dexOptions {
        javaMaxHeapSize "4g"
    }
    lintOptions {
        abortOnError false
    }

    aaptOptions {
        ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
    }
}

내게 맞게 수정했다.

당연한걸 수정한거지만... 초반 에러의 원인은 이게 아니었을것임..


 

[ 빌드 에러 "각종" 해결 방법 ]
- 참고로 플러그인은 애드몹과 인앱결제만 사용.

- keystore 설정
- project setting > Player > Publishing Settings > Build 아래처럼 체크

- project setting > Player > Other Settings > Minimum API Level, Target API Level 수정
   -- 각 30, 32로 해둠.
- mainTemplate.gradle 파일에 multiDexEnabled true 이거랑 여러개 추가.(multiDex에러 검색하면 추가할거 여러개 나옴)

일단, 이정도.. 정리하면서 했어야 했는디..

728x90
반응형
728x90

 

using GoogleMobileAds.Api;
using UnityEngine;


public class AdMobManager : MonoBehaviour
{


    // These ad units are configured to always serve test ads.
#if UNITY_ANDROID
    private string _adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
  private string _adUnitId = "ca-app-pub-3940256099942544/1712485313";
#else
  private string _adUnitId = "unused";
#endif

    public void Start()
    {
        // Google 모바일 광고 SDK를 초기화합니다.
        MobileAds.Initialize((InitializationStatus initStatus) =>
        {
            // 이 콜백은 MobileAds SDK가 초기화되면 호출됩니다.
            LoadRewardedAd();
        });
    }

    private RewardedAd rewardedAd;

    public void LoadRewardedAd()
    {
        // 새 광고를 로드하기 전에 이전 광고를 정리하십시오.
        if (rewardedAd != null)
        {
            rewardedAd.Destroy();
            rewardedAd = null;
        }

        Debug.Log("Loading the rewarded ad.");

        // 광고를 로드하는 데 사용되는 요청을 생성합니다.
        var adRequest = new AdRequest();
        adRequest.Keywords.Add("unity-admob-sample");

        // 광고 로드 요청을 보냅니다.
        RewardedAd.Load(_adUnitId, adRequest,
            (RewardedAd ad, LoadAdError error) =>
            {
                RegisterEventHandlers(ad);

                // 오류가 null이 아니면 로드 요청이 실패한 것입니다.
                if (error != null || ad == null)
                {
                    Debug.LogError("보상형 광고가 광고를 로드하지 못했습니다. " +
                                   "with error : " + error);
                    return;
                }

                Debug.Log("응답으로 로드된 보상형 광고 : " + ad.GetResponseInfo());

                rewardedAd = ad;
            });
    }

    public void ShowRewardedAd()
    {
        if (rewardedAd != null && rewardedAd.CanShowAd())
        {
            rewardedAd.Show((Reward reward) =>
            {
                // 보상 주는 곳.
                Debug.Log(" 보상 주는 곳 // " + reward.Type + " // " + reward.Amount);
            });
        }
    }

    // RewardedAd는 일회용 객체입니다. 즉, 보상형 광고가 표시된 후에는 객체를 다시 사용할 수 없습니다. 다른 보상형 광고를 요청하려면 새 RewardedAd 객체를 만들어야 합니다.
    // 다음 노출 기회에 맞게 보상형 광고를 준비하려면 OnAdFullScreenContentClosed 또는 OnAdFullScreenContentFailed 광고 이벤트가 발생한 후 보상형 광고를 미리 로드합니다.
    private void RegisterEventHandlers(RewardedAd ad)
    {
        // 광고에서 수익이 발생한 것으로 추정될 때 발생합니다.
        ad.OnAdPaid += (AdValue adValue) =>
        {
            Debug.Log("광고에서 수익이 발생한 것으로 추정될 때 발생합니다. " + adValue.Value + " // " + adValue.CurrencyCode);
        };
        // 광고에 대한 노출이 기록될 때 발생합니다.
        ad.OnAdImpressionRecorded += () =>
        {
            Debug.Log("광고에 대한 노출이 기록될 때 발생합니다.");
        };
        // 광고에 대한 클릭이 기록될 때 발생합니다.
        ad.OnAdClicked += () =>
        {
            Debug.Log("광고에 대한 클릭이 기록될 때 발생합니다.");
        };
        // 광고가 전체 화면 콘텐츠를 열 때 발생합니다.
        ad.OnAdFullScreenContentOpened += () =>
        {
            Debug.Log("광고가 전체 화면 콘텐츠를 열 때 발생합니다.");
        };
        // 광고가 전체 화면 콘텐츠를 닫을 때 발생합니다.
        ad.OnAdFullScreenContentClosed += () =>
        {
            Debug.Log("광고가 전체 화면 콘텐츠를 닫을 때 발생합니다.");
            // 다음 보상형 광고 미리 로드
            LoadRewardedAd();
        };
        // 광고가 전체 화면 콘텐츠를 열지 못했을 때 발생합니다.
        ad.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError("광고가 전체 화면 콘텐츠를 열지 못했을 때 발생합니다." + " with error : " + error);
            // 다음 보상형 광고 미리 로드
            LoadRewardedAd();
        };
    }

}

 

728x90
반응형
728x90

 

문제: 애니메이션에 이벤트 키를 추가 해도 함수 인식을 못한다.

이벤트 키 추가
선택할 함수가 아무것도 나오지 않는다.

1. 내가 만든 함수를 연결할 거라면 스크립트가 연결되어 있는지 확인한다.
2. 기본 제공 함수도 보이지 않는다면 오브젝트에 해당 컴포넌트(Image라던가, Text 라던가..)가 추가되어 있는지 확인한다.

728x90
반응형
728x90

볼륨 10일때
볼륨 100일때

 

문제1 : 이미지의 크기를 늘이거나 줄일때 이미지가 눌리거나 늘어난다.
해결방법: 'sprite editor'를 이용한다.

1. project 창에서 이미지를 클릭한다.

 

2. Inspector창에서 Sprite Editor 버튼을 누른다.

 

3. 이미지를 줄이거나 늘려도 비율이 바뀌지 않을 부분을 정해준다.
- 초록색 선을 움직여 범위를 정하면된다.
- 범위를 정하지 않은 가운데 부분이 늘어나거나 줄어들게된다.
- 오른쪽 상단에 Apply를 눌러서 적용시킨다.

 

4. Image Type을 Sliced로 넣는다.

 

<결과1>

volume이 10일때
volume이 100일때

 


 

문제2 : 엄청 작거나 많이 크거나 하면 스프라이트 에디터에 적용한 것과 별개로 또 깨진다.
이유 : 텍스처(Texture)의 해상도와 스프라이트의 크기 사이에 불일치가 발생하기 때문이다.
해결 : 이를 해결하기 위해서는 크기를 조절할 때 텍스처의 해상도를 고려해야 한다.
1. 스프라이트의 크기를 변경할 때에는 텍스처 자체의 해상도를 변경하는 것이 아니라, 스프라이트가 참조하는 텍스처의 픽셀 밀도를 조정해야 한다.
2. 이는 텍스처의 'Pixels per Unit Multiplier' 값을 조절하는 것으로 해결했다.

1 -> 2.5 (내 경우에는 2.5가 적당)

 

<결과2>

volume이 10일때
volume이 100일때

 

728x90
반응형
728x90

조건: 목록을 프리팹으로 만들었다. 목록 각 항목 안에 버튼이 있다.
목적: 목록 항목의 버튼을 누르면 목록 항목에 변화를 주고싶다.

 

1. 목록 프리팹을 만드는 컴포넌트를 SetActive(false), SetActive(true)
- 비활성화 후 다시 활성화 시키면 스크립트 사이클이 다시 시작되기때문에 목록을 다시 만든다. 

728x90
반응형
728x90

원하는 기능 : 애니메이션이 끝나고 n초 후에 다시 재생.
해결: 해결 방법은 많겠지만, 내가 선택한건 애니메이션 이벤트와 커스텀 함수를 이용했다.

  1. 애니메이션을 클릭해서 인스펙터창에 나온 Loop Time을 해제한다.

  1. 애니메이션이 끝나면 들어올 스크립트를 생성한다.
    // 변수 생성
    Animator anim;


    void Awake()
    {
        // 스크립트가 붙어있는 오브젝트에서 Animator 컴포넌트 가져오기.
        anim = GetComponent<Animator>();
    }

    // IEnumerator: 코루틴만의 반환형 인터페이스. (앞에 I가 붙는 것은 인터페이스라고 한다)
    // yield : 코루틴의 반환 키워드
    IEnumerator EndAnim(){
        // new Wait을 기입하고 자동완성 부분을 보면 유니티에서 제공하는 함수가 몇가지 있다. 
        // 그 중에 나는 5초 딜레이가 필요하기 때문에 아래와 같이 작성한다.
        yield return new WaitForSeconds(5f);

        // loop 를 걸어두지 않아서 멈추어있는 애니메이션을 다시 플레이.
        // DeadEnemy 0: 재생할 애니메이션 클립 이름
        // -1: 모든 레이어를 대상
        // 0f: 애니메이션의 시작 시간
        anim.Play("DeadEnemy 0", -1, 0f);
    }

 

  1. 애니메이션 오브젝트에 스크립트 연결
  2. 애니메이션 끝난 부분에, 이벤트를 걸어준다.
    ㄱ. 마우스를 드래그해서 하얀색 세로줄을 이벤트 걸어줄 위치해 놓는다.
    ㄴ. 왼쪽 북마크 모양을 눌러 이벤트를 걸어준다.
    ㄷ. 생성된 북마크(오른쪽 빨간 네모상자)를 클릭하면 오른쪽에 인스펙터창이 열린다.

 

  1. 내가 만든 함수를 선택한다. ( 주의할 점은 오브젝트에 위에 만든 스크립트를 넣어와야 EndAnim이 보인다.)

 

 

 


드디어 게임이 나왔드아.... ㅜ
유달리 힘들었던 게임이다. 애정이 들어가서 그른가...
누군가 이 글을 본다면 한 번 씩 해보시길 바람...아니 부탁함다.
아득바득 살고있는 중생이어라.. 5점 리뷰도 달아주심 정말 감사합니닷...

진술로만 해결해야하는 추리게임!
난이도는 높지만 도전해 보세요!
갑자기 홍보말투 ㅋㅋㅋㅋ

"초동수사 - 증언/증거 추리게임"

구글플레이스토어
https://play.google.com/store/apps/details?id=com.loomiloomi.crimescene&pcampaignid=web_share

앱스토어
https://apps.apple.com/us/app/%EC%B4%88%EB%8F%99%EC%88%98%EC%82%AC-%EC%A6%9D%EC%96%B8-%EC%A6%9D%EA%B1%B0-%EC%B6%94%EB%A6%AC%EA%B2%8C%EC%9E%84/id6499072416

728x90
반응형

+ Recent posts