336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

[Unity3D] Mac 에셋번들(asset bundle) 오류


Mac에서 에셋번들(asset bundle)을 만들고 파일질라(FileZila)를 통해서 업로드를 했는데


Error while downloading Asset Bundle: Failed to decompress data for the Assetbundle.. 


이런 오류가 나타났습니다.




잘 사용하고 있었던건데 금일 수정한것 때문에 그런것인지 당황했네요.


검색을 조금해보니 전송유형이 문제였습니다.


전송유형이 자동으로 되어있었습니다.



해결을 위해 전송유형을 바이너리(Binary)로 변경해주시면 됩니다.




쉽게 해결될 일이었는데 시간을 많이 소비했네요.


Error while downloading Asset Bundle: Failed to decompress... 


이런 문제로 당황스러운 분들은 참고하시면 좋을 것 같습니다.


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

[Unity3D] 안드로이드 플러그인 만들기(안드로이드 스튜디오 2.3.3)


build.gradle

 


기존 포스팅에서 안드로이드 스튜이도 2.1.1로 플러그인을 만들었는데,

 

안드로이드 스튜디오가 업데이트 되면서 release 폴더가 안생기는 문제가 있었습니다.

 

그래서 많은 분들이 댓글을 달아주셨는데, 이제서야 포스팅을 하네요.

 

간략하게 쓰도록 하겠습니다. (순서 이미지는 다 있습니다.)

 

잘 안되시는 분들은 기존 포스팅 참고 하시면 수월하십니다.

 

 

안드로이드 스튜디오(Android Studio)를 실행하여 New Proejct를 하고,

 

Application name과 Company domain을 써줍니다.

 

실제 사용은 하지 않을 클래스 입니다. 아무거나 치셔도 됩니다. 그리고 Next를 눌러줍니다.

 

 

 

Phone과 Tablet에서 사용할 예정이니 그대로 Next를 눌러줍니다.

 

 

 

그리고 Empty Activity를 선택하고 Next를 눌러줍니다.

 

 

아래 체크 박스들은 쓸 일이 없으므로, 체크 해제 해주시고,

 

Activity Name도 그냥 두시기 바랍니다. (사용하지 않습니다)

 

그리고 Next를 눌러줍니다.

 

 

완료되었으면, 이제 File->New Module을 눌러줍니다.

 

 

 

기존에는 프로젝트 생성해서 바로 했지만, 이제 모듈을 추가해서 할 예정입니다.

 

Android Library를 선택하고 Next를 눌러줍니다.

 

 

 

라이브러리 이름을 작성하시고 Finish를 눌러줍니다.

 

 

 

방금 만든 모듈 루트에서 마우스 오른쪽을 눌러

 

Open Module Settings를 눌러줍니다.

 

UnityActivity를 사용하기 위해, Unity에 있는 classes.jar를 추가할 것입니다.

 

 

 

방금 만든 모듈이 선택되어있는지 재 확인 하시고,

 

Dependenceis로 가서 + 버튼을 누른 후 Jar dependency를 눌러줍니다.

 

 

 

현재 저는 Unity 5.3를 사용중입니다.(classes.jar 파일의 경로가 예전 버전과 달라졌습니다.)

 

만약 해당 파일이 존재하지 않는다면(예전 버전이라면)

 

이전 포스팅을 참고해주세요.

 

classes.jar 파일을 복사해서, 다음 경로(바로 윗 단계에서 경로 확인가능)에 붙여넣기 해줍니다.

 

 

 

넣어주고 다음 화면으로 돌아오면,  아래 이미지처럼 jar파일이 들어간 것을 확인할 수 있습니다.

 

 

 

확인을 눌러주시고, 좀전에 만든 모듈의 다음 패키지에서

 

마우스 오른쪽을 눌러 새로운 Java Class를 만들어 줍니다.

 

 

 

이름은 MyPluginActivity로 하겠습니다. 그리고 확인을 눌러줍니다.

 

 

 

거의 완료가 되었습니다.

 

테스트 할 수 있도록 몇개의 함수를 만들어 줍니다.

 

 

 

 

그리고 좌측에 Gradle을 통해 jar파일을 만들 예정입니다.

 

myplugin 모듈 이름이 써있는 build.gradle을 더블클릭해서

 

스크립트를 열어줍니다.

 

다음은 몇가지를 추가하여 작성한 파일입니다.

 

 

 

위 스크립트 내용입니다.

apply plugin: 'com.android.library'

android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
publishNonDefault true
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
testCompile 'junit:junit:4.12'
compile files('libs/classes.jar')
}

task deleteObjectJar(type: Delete){
delete 'release/AndroidPlugin.jar'
}

task exportJar(type: Copy){
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'AndroidPlugin.jar')
}

exportJar.dependsOn(deleteObjectJar, build)

 

 

다 작성하였으면 Build->Clean Project를 한번 해줍니다.

 

 

 

그리고 안드로이드 스튜디오 우측에 있는 Gradle을 눌러

 

myplugin->Tasks->other->exportJar를 더블클릭해줍니다.

 

 

 

그러면 다음처럼 프로젝트 폴더 release쪽에 jar파일이 나온것을 확인할 수 있습니다.

 

 

도움되셨길 바랍니다.

 

질문은 댓글 달아주세요^^

 


******************* 추가 *****************

Plugin 모듈을 추가 하셨는데, 그 모듈의 gradle 파일을 첨부하였습니다.


모듈 gradle을 설정하고, 이를 실행시켜야 release 폴더가 나옵니다.


프로젝트 만들 때 지정한 그 프로젝트가 아니라, 


추가한 모듈입니다. 이점 헷갈리시지 마세요.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


유니티3D 안드로이드(Android) 플러그인(Plugin) 만들기(추가)


[UNITY] 안드로이드 플러그인 만들기 에 추가적으로 하나더 써보려고 합니다.


Java 코드단에서 UnityPlayerActivity를 상속 받는 곳에서 구현을 했었는데,


그게 아닌 타 클래스 만들어서 하는 부분도 추가합니다. 


Java에서 타 클래스를 만들고 구현을 한 다음 Unity에서 클래스를 찾아서 호출하면 됩니다.


간단히 예를 들겠습니다.



< Java >


1. 프로젝트 만들고(패키지명은 원하시는걸로), 클래스를 하나 추가합니다.


여기에서는 TestAClass가 새로 생성한 클래스 입니다.




2. 기본 클래스 파일입니다. UnityPlayerActivity를 상속해 줍니다.


* UnityPlayerActivity상속없이 자바 클래스만 추가해서 되는지는 아직 못해봤네요. 혹 해보신분 댓글로 부탁드립니다.




3. 유니티애서 호출할 클래스 입니다. 


간단히 GetSum()이라는 함수만 추가하겠습니다.





< Unity >

* 우선 AndroidManifest.xml 확인해주세요. 많은 분들이 패키지명이 달라서 안된경우가 많았습니다.


using UnityEngine;
using System.Collections;

public class PluginCalling : MonoBehaviour {

    private static AndroidJavaObject myObj;

    string messge = "init";

	// Use this for initialization
	void Start () {
#if UNITY_ANDROID && !UNITY_EDITOR
	    myObj = new AndroidJavaObject( "com.mine.androidplugin.TestAClass" );
#endif
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    void OnGUI()
    {
        // 이렇게 접근하는 방법은, static이나 non-static 모두
        // 동일한 방법으로 접근 가능하다
        if (GUI.Button(new Rect(100, 100, 100, 50), "GetSum"))
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            messge += ("\n" + myObj.Call("GetSum", 123, 456).ToString());
#endif
        }

        GUI.Label(new Rect(Screen.width / 2 - 350, Screen.height / 2 - 150, 700, 300), messge);
    }
}


별거 없네요. 그냥 AndroidJavaObject로 오브젝트 생성하고 호출하는 것 입니다.


도움되셨길 바랍니다.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


FTP 파일 업로드 하기


< 테스트 파일 >

PUploader.zip



사실 테스트 코드 자체는 C# 프로젝트로 하였습니다.


그러나 유니티에서도 동일하게 사용 되므로, 


유니티 카테고리로 설정했습니다.(유니티 확인 완료)


에셋번들을 만들고, FTP로 파일을 업로드(Upload) 해야 하는데, 


매번 직접 해주어야 하니 불편하더라구요.


그래서 시간 조금 투자해서 FTP 파일 업로드를 테스트 했습니다.


* 정말 적은 시간으로 만든거라.. 버그가 많습니다.  코드만 참조하시길.



제 FTP 폴더입니다. 


UploadTest라는 폴더에다가 테스트 하려고 합니다.




테스트 프로그램입니다.


주소, 아이디, 비번, 그리고 폴더경로(이 하위에 애들이 FTP로 업로드 됩니다)를


설정하고 업로드를 누르면 올라갑니다.


실제 유니티에서 할 때에는 주소, 아이디 등을 코드에 박고 하세요.


테스트 프로그램이라서 이렇게 작성한 것입니다.




폴더를 선택하고 업로드를 누르면


정상적으로 올라간 리스트가 나타납니다.




콘솔 창에서도 결과를 볼 수 있습니다.




실제 FTP를 확인해 보면, 


제가 올린 폴더와 파일들이 올라가 있습니다.


테스트 성공.




주요 코드만 올리겠습니다.


즉, 실제 유니티에서 사용할 것만.


< FTP UPLOAD 코드 >


// 폴더 정보 가져오기.
                DirectoryInfo info = new DirectoryInfo(folder);
                // 우리는 루트 폴더를 제외하고 하므로, 전체 경로에서 루트 경로를 제거합니다.
                string folderName = info.FullName.Replace(_strPath, "");

                Console.WriteLine("TargetPath : " + URL + folderName);
                // FTP 주소 + 폴더 경로를해서 폴더를 만들겠습니다.
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(URL + folderName);

                // 비번 아이디를 치고, 여러 설정을 해줍니다.
                // 자신에게 맞게 설정하시면 됩니다.
                request.Credentials = new NetworkCredential(ID, PW);
                request.UsePassive = true;
                request.UseBinary = true;
                request.KeepAlive = false;
                // 폴더를 마들 것이므로, MakeDirectory로 해줍니다.
                request.Method = WebRequestMethods.Ftp.MakeDirectory;
                // 파일을 업로드 할 때에는 다음 메소드를 선택합니다.
                //request.Method = WebRequestMethods.Ftp.UploadFile;

                try
                {
                    // 이제 디렉토리를 만든다고 FTP로 요청을 합니다.
                    FtpWebResponse res = (FtpWebResponse)request.GetResponse();
                    // 요청이 실패하면 CATCH로 넘어갑니다.
                    // 요청이 완료 되었으므로, 리스트에 추가 합니다.
                    m_lUploadList.Add(URL + folderName);
                }
                catch (WebException ex)
                {
                    // 예외처리.
                    FtpWebResponse response = (FtpWebResponse)ex.Response;

                    switch (response.StatusCode)
                    {
                        case FtpStatusCode.ActionNotTakenFileUnavailable:
                            {
                                Console.WriteLine("CreateFolders ] Probably the folder already exist : " + folderName);
                            }
                            break;
                    }
                }


현재 코드는 예외처리 들이 하나도 안되어 있는 거네요.


실제 유니티(에셋번들 자동화)에서 사용할 때에는 


많은 예외처리가 필요할 수 있습니다.


도움되셨길 바랍니다.


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


유니티 버전 : 4.6.9


유니티 3d 4.x (Unity3d 4) 에셋번들 만들기 및 사용


이전에 유니티 5.x 에서 에셋번들을 만들었는데, 


유니티 4.x 에서 만드는 것도 포스팅합니다.



우선 씬에 다음처럼 큐브 하나를 만들겠습니다.


참고로 저는 미리 프리팹화 시켜서 Cube가 파란색입니다. (무시하세요)




리고 에셋번들을 만들 폴더를 Bundle이라는 이름으로 만들겠습니다.


그 하위로 A, B, C 폴더를 만들고


각 폴더안에 좀전에 만든 Cube를 프리팹 화 시키겠습니다.


정리하면 다음과 같습니다.


Bundle - A - Cube.prefab

           - B - Cube1.prefab

           - C - Cube2.prefab




에셋번들로 만들 항목들이 정해졌으니, 


이제 에디터를 하나 만들어 에셋번들로 만들겠습니다.


참고 : Creating Asset Bundlesin Unity 4


우선 편의를 위해 Editor 폴더를 만들고, 


BundleBuilder 라는 클래스를 하나 만들겠습니다.




자세한 코드 내용은 주석으로 설명하였습니다.


< BundleBuilder.cs 코드 >


using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

public class BundleBuilder : MonoBehaviour {

    [MenuItem("Assets/Build AssetBundle")]
    static void ExportResource()
    {
        // 저장할 에셋번들 이름.
        // 경로가 없을 경우 최상위(Assets상위)에 저장된다.
        // 현재 저장경로는 Assets/myAssetBundle 이다.
        string path = Application.dataPath + "/myAssetBundle";
        Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);

        // 현재 선택된 항목
        // 게임오브젝트만 해당.
        // 만약 씬에 있는 항목이라면, activeObject대신 activeTransform 사용권장.
        if(Selection.activeObject != null)
            Debug.Log("Current : " + Selection.activeObject.name);
        // 선택된 모든(하위 포함) 항목들
        foreach (Object sel in selection)
        {            
            Debug.Log("Path ; " + sel.ToString() + ", path :"+ AssetDatabase.GetAssetPath(sel));
        }

        // Selection.activeObject가 들어간 곳이, mainAsset이 된다.
        // 세번째 인자는 에셋번들을 저장할 경로(파일명 포함)
        // 현재 테스트로 Android 플랫폼으로 하도록 한다.
        BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                                       BuildAssetBundleOptions.CollectDependencies
                                     | BuildAssetBundleOptions.CompleteAssets, BuildTarget.Android);
    }
}



코드를 작성하였다면, 저장을 해주세요.


그러면 다음처럼 메뉴가 생겼을 것입니다.


아까 만든 Bundle폴더를 선택하고, 


Build AssetBundle메뉴를 선택하겠습니다.




그러면 이렇게 에셋번들 만들기를 시작합니다.




이제 프로젝트 루트 폴더(Assets)를 가보면, 


우리가 만든 myAssetBundle이라는 파일이 생겼을 것입니다.


* 확장자는 없어도 되고, 마음대로 넣으셔도 됩니다.




이제 실제 에셋번들을 로드하도록 하겠습니다.


저는 Loader라는 클래스를 만들겠습니다.


< Loader.cs 코드 >


using UnityEngine;
using System.Collections;

public class Loader : MonoBehaviour {

	// Update is called once per frame
	void Update () {
        if (Input.GetKeyDown(KeyCode.A))
        {
            StartCoroutine(Load());
        }
	}

    IEnumerator Load()
    {
        // 불러올 파일 경로.
        // pc의 경우 file:/// 로 시작하셔야 합니다.
        string path = "file:///" + Application.dataPath + "/myAssetBundle";
        // 캐시에 있을 경우 그대로 로드하고, 그렇지않은 경우 해당 경로에서 다운로드하여 캐시저장.
        WWW ww = WWW.LoadFromCacheOrDownload(path, 0);
        // 받을 때까지 대기합니다.
        yield return ww;
        // 에러가 있을 수 있으므로, 체크합니다.
        if (string.IsNullOrEmpty(ww.error) == false)
        {
            Debug.LogError("Error!! : " + ww.error);
        }
        // 이제 에셋번들을 가져오겠습니다.        
        AssetBundle bundle = ww.assetBundle;
        // 우리가 만든 어셋번들에는 Cube, Cube1, Cube2가 있습니다.
        // 세개 다 로드하겠습니다.
        if (bundle != null)
        {
            // 우리는 폴더을 선택하여 에셋번들을 만들었으므로, 
            // Selection.activeObject가 없습니다.
            // 즉, bundle.mainAsset이 없습니다.
            // 하위에 있는 프리팹을 이름으로 로드해야 합니다.
            // bundle.mainAsset <= null.
            GameObject gObj = bundle.Load("Cube", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjA not found");            
            }

            Instantiate(gObj);

            gObj = bundle.Load("Cube1", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjB not found");
            }

            Instantiate(gObj);

            gObj = bundle.Load("Cube2", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjC not found");
            }

            Instantiate(gObj);
            // 모두 사용했다면, unload하겠습니다.
            // 실제 매니저를 만드실 때에는 실시간으로load, unload를 해도 되겠지만, 
            // 그럴필요는 없습니다.
            // 해당 에셋번들을 들고 있어도 무관합니다.(압축되어있는 상태이므로)
            // unload를 false로 하면 에셋번들 내에 활성화 되어있는 오브젝트는 
            // unload되지 않습니다.
            // 만약 true로 하면, 활성화 되어있어도 unload되어버립니다.
            // 이럴 경우 missing이 날 수 있습니다.
            bundle.Unload(false);
        }
        else
        {
            Debug.Log("null");
        }
    }
}


코드 작성이 완료되었으면, 게임오브젝트에 


스크립트를 추가해주세요.


그리고 실행을 시켜줍니다.


우리는 A키를 누르면 로드하도록 되어있습니다.


A를 눌러보면 다음처럼 로드되는것을 확인할 수 있습니다.


< 결과화면 >



유니티4 에셋번들 만들 때 보면 


BuildPipeline.PushAssetDependencies() 와 Pop이 있는데


다른 에셋번들 사이에서 의존성을 유지시킬 때 사용합니다.


참고 : BuildPipeline.PushAssetDependencies


궁금한 점은 댓글 달아주세요.




336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


유니티3D 광고 붙이기(TEST 버전)


유니티에서 제공하는 광고를 붙여보려 합니다.


우선 실제 스토어에 등록된 것이 없으니 테스트용으로 하겠습니다.


그리고, Android가 테스트가 편하니 Android용 Ads를 달도록 하겠습니다.



우선 unity3d.com에 접속을 합니다.


그리고 상단에 서비스 메뉴가 있는데, 그쪽으로 들어갑니다.




그리고나서 하단에 보시면


UNITY ADS쪽에 자세히 보기가 있습니다.


클릭합니다.




이제 하단에 보이는 


지금 수익화 시작을 눌러줍니다.




그리고 아래 나오는 버튼을 눌러 


유니티에 로그인을 해 줍니다.




로그인이 완료되면 다음과 같은 화면을 보실 수 있습니다.


광고를 보여줄 게임이 필요하므로, 


새 게임 추가를 누르도록 하겠습니다.




Android로 테스트를 한다고 했습니다.


안드로이드 아이콘을 눌러 줍니다.


그럼 2단계가 나오는데, 현재 서비스 하고 있는 게임이 아니므로


하단에 "여기"를 눌러줍니다.




그럼 출시되지 않은것으로 나옵니다.


대충 이름을 써주고, 게임추가를 눌러줍니다.




3단계(마지막 단계)가 보입니다.


테스트용이므로, 아래처럼 선택하겠습니다.


* 실제 게임에서는 해당 게임에 맞도록 하셔야 합니다.




이제 광고를 보여줄 수 있는 게임이 추가되었습니다.


광고 설정을 위하여 추가한 게임이름을 눌러줍니다.




광고 설정을 위해 수익화 설정 메뉴를 눌러주고, 


고급 설정 보기 를 눌러줍니다.




그러면 기본적으로 세팅된 두개의 광고 리스트가 보입니다.


첫번째 광고는 보상이 없는, 즉 사용자가 스킵할 수 있는 광고 입니다.


저는 광고를 보고 보상을 주려고 합니다.


그러므로, 두번째 Rewarded광고를 사용할 것입니다.


그리고 아이디 가 있는데, 보여줄 광고에 필요하니 기억해야 합니다.


이제 설정을 눌러줍니다.




해당 광고의 상세페이지 입니다.


현재는 바꿀것이 없습니다. 차 후 변경할 일이 있으면 여기에서 하시면 됩니다.


그냥 저장을 눌러줍니다.




이제 광고 설정을 끝이 났습니다.


실제 유니티에서 광고를 달아보도록 하겠습니다.


유니티를 실행 하시고, 에셋스토어를 들어갑니다.


그리고 unityad라고 치시면 Unity Ads 에셋이 보입니다.


눌러서 다운받고, 패키지를 불러들입니다.




패키지를 잘 로드했다면, 다음처럼 Plugin에 Android와 iOS가 생겼을 것입니다.


이게 보이시면 잘 되신겁니다.




그리고 광고 보기 테스트를 위해 


다음처럼 화면을 구성하겠습니다.


가운데 검정색 네모는 광고보기 버튼입니다.


참고로 저는 NGUI로 테스트 하고 있습니다. 


참고 : [NGUI] 버튼과 레이블




광고를 보기위해 초기화와 보여주기 기능이 필요합니다.


저는 UIMan이라는 클래스를 만들도록 하겠습니다.


작성 후 게임오브젝트에 링크시켜주시기 바랍니다.


< UIMan.cs 코드 >


using UnityEngine;
using System.Collections;

// 광고 사용하기.
using UnityEngine.Advertisements;

public class UIMan : MonoBehaviour {

    // 광고 옵션값
    ShowOptions m_cShowOptions = new ShowOptions();
    // 광고보기 버튼.(광고 준비가 안될 때에 비활성 시키려고 들고있음)
    public GameObject m_gObjEventButton;
    // 보상 테스트
    int m_nGold = 0;
    // 현재 광고상태    
    ShowResult m_eResult = ShowResult.Failed;
    // 혹시 버튼 클릭했는데, 콜백이 안넘어 오는지 체크위함.
    bool m_bClicked = false;
    // 광고 클릭 카운트
    int m_nClickCount = 0;

    void Awake()
    {
        // 광고 최초 초기화 해준다.
        // Initialize(광고 번호, 테스트 모드인가)
        Advertisement.Initialize("120256", true);
        // 광고 완료할 때 처리할 콜백함수를 넣어준다.
        // System.Action 형태
        m_cShowOptions.resultCallback = OnAdsShowResultCallBack;
    }

	// Update is called once per frame
	void Update () {
        // 광고가 사용가능 한지 여부를 체크한다.
        // Adverisement.IsReady(광고 아이디)
        // 아까 생성한 곳 보면 광고 아이디가 있습니다.
        // 여러 광고중 하고자 하는 아이디를 넣어주면 됩니다.
        if (Advertisement.IsReady("rewardedVideoZone"))
        {
            m_gObjEventButton.SetActive(true);
        }
        else
        {
            m_gObjEventButton.SetActive(false);
        }
	}

    // 광고 버튼 클릭을 눌렀을 때 발동.
    public void OnClickButton()
    {
        m_bClicked = true;
        m_nClickCount++;
        // 해당 아이디의 광고를 보여준다.
        Advertisement.Show("rewardedVideoZone", m_cShowOptions);
    }
    // 광고 보기 완료 후 호출되는 콜백함수
    void OnAdsShowResultCallBack(ShowResult _result)
    {
        m_eResult = _result;
        // 정상적으로 완료 될 때에만 처리하도록 하겠습니다.
        if (_result == ShowResult.Finished)
            m_nGold += 50;

        // 정상적으로 CallBack이 들어왔다면, 클릭여부 false.
        m_bClicked = false;
    }

    void OnGUI()
    {        
        // 현재 보상받은거.
        GUI.Label(new Rect(10, 50, 500, 30), "Gold : " + m_nGold.ToString());
        // 콜백 결과
        GUI.Label(new Rect(10, 100, 500, 30), "Result : " + m_eResult.ToString());
        // 광고 클릭 카운트와, 클릭상태 여부 표시.
        GUI.Label(new Rect(150, 100, 500, 30), "ClickCount : "+ m_nClickCount.ToString() 
                + ", Clicked : "+ m_bClicked.ToString());
    }
}


모두 완료가 되었습니다.


Android 단말기에 넣고 테스트를 하겠습니다.


< 최초 실행화면 >



< 광고 보기 버튼 클릭 >



< 광고 보고 난 후 결과 > 


저도 실제 광고를 달아보지 않아서, 실제 달때에는 어떻게 다른지 아직은 모르겠네요.


실제 광고를 달고 나서 다른 점이 있을 경우


다시 포스팅 하도록 하겠습니다.


도움되셨길 바랍니다.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

유니티3D 안드로이드(Android) 플러그인(Plugin) 만들기 Part 2.


안드로이드 스튜디오(Android Studio) 2.1.1 기준입니다.

 

* 안드로이드 스튜디오(Android Studio) 상위 버전 분들은 여기 를 눌러 확인바랍니다. *


 

* 유니티와 통신하는 방법은 몇가지가 있습니다.


그중 하나를 선택해서 테스트 하였습니다.


 참고 : http://docs.unity3d.com/Manual/PluginsForAndroid.html



유니티를 열고 새 프로젝트를 만듭니다.


그리고 Assets 및에 Plugins 라는 폴더를 만듭니다.


* 플러그인들은 무조껀 이 폴더에 있어야 합니다.


그리고 그 하위에 Android 폴더를 만듭니다.


* 각 플랫폼 별로 정해진 폴더를 사용해야 합니다.




Android의 플러그인을 사용하기 위해서는


Manifest파일을 적용시켜줘야 합니다.


Part1에서 만든 Manifest를 가져오기 위하여, 


다음 폴더에 가서 복사를 합니다.




그리고 Part 1에서 만든 플러그인(.Jar파일)과 


Manifest파일을 해당 폴더에 넣어줍니다.




여기에서 중요한 점은 Bundle Identifier를 맞춰주어야 합니다.


우리는 이전 패키지 이름을 


com.test.plugintest로 만들었기 때문에, 동일하게 적어주겟습니다.


(해당 Identifier로 Jar파일의 패키지를 읽어들이기 때문에 맞춰주어야 합니다)




다음은 저의 AndroidManifest.xml 파일입니다.


혹시 모르니 비교해보시기 바랍니다.




이제 중간 과정은 끝났으니, 실제 코드로 연동을 하겠습니다.


주석으로 설명 달아두었으니 참고하시기 바랍니다.


< PluginTest.cs 코드 >


using UnityEngine;
using System.Collections;

public class PluginTest : MonoBehaviour {

    string messge = "init";
    AndroidJavaClass myCls;
    AndroidJavaObject myObj;

    //// Use this for initialization
	void Start () {
        // 새로룬 오브젝트를 만들지 않고, com.unity3d.player.UnityPlayer의 
        // static 멤버에 접근하기 위해 AndroidJavaClass를 사용한다.
        // (사실 Android UnityPlayer가 자동으로 인스턴스를 생성해준다)
        myCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        // 그리고 static 필드인 currentActivity를 접근한다.
        // 그리고 이경우 AndroidJavaObject를 사용한다. 
        // 이유는 실제 필드 타입이 android.app.Activity이고
        // 이건 java.lang.Object를 상속받는다. 
        // 그리고, non-primitive 타입은 무조껀 AndroidJavaObject로 접근해야한다.
        // 예외 : strings.
        myObj = myCls.GetStatic("currentActivity");        
	}
    void OnGUI()
    {
        // 이렇게 접근하는 방법은, static이나 non-static 모두
        // 동일한 방법으로 접근 가능하다
        if (GUI.Button(new Rect(100, 100, 100, 50), "StaticInt"))
        {   
            messge += ("\n" + myObj.CallStatic("GetStaticInt", 123).ToString());
        }

        if (GUI.Button(new Rect(100, 200, 100, 50), "StaticString"))
        {
            messge += ("\n" + myObj.CallStatic("GetStaticString", "StaticString"));
        }

        if (GUI.Button(new Rect(100, 300, 100, 50), "Int"))
        {
            messge += ("\n" + myObj.Call("GetInt", 456).ToString());
        }

        if (GUI.Button(new Rect(100, 400, 100, 50), "String"))
        {
            messge += ("\n" + myObj.Call("GetString", "String"));
        }
      
        GUI.Label(new Rect(Screen.width / 2 - 350, Screen.height / 2 - 150, 700, 300), messge);
    }
}



< 결과 화면 >




처음에도 말했듯이 연동방법에는 몇가지가 있습니다.


자신이 편한걸로 하면 되지 않을까하네요.


그리고 문서를 보니 통신하는게 부하가 많이 발생한다고 합니다.


가능하면 최적의 호출로 해야겠네요.


도움되셧길 바랍니다.



* 플러그인만들기 추가



336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

유니티3D 안드로이드(Android) 플러그인(Plugin) 만들기 Part 1. 

안드로이드 스튜디오(Android Studio) 2.1.1 기준입니다.

 

* 안드로이드 스튜디오(Android Studio) 상위 버전 분들은 여기 를 눌러 확인바랍니다. *


 

* 이 글을 보시는 분들은 필수적으로

Android Studio 2.1.x가 설치되어 있어야 합니다.

또한 개인적으로 구글링한 방법이니 참고만 하시기 바랍니다.



안드로이드 스튜디오(Android Studio)를 실행하여 New Project를 합니다.


Application name과 Company Domain을 써줍니다.


저는 다음처럼 하겠습니다.




그리고 Next를 누르게 되면 다음과 같은 화면이 나옵니다.


저는 Phone과 Tablet에서 실행 하므로 다음처럼하였습니다.


그리고 Minimum SDK는 각 상황에 맞도록 설정하면 됩니다.




그리고 Next를 누르면 Activity 설정이 나오는데 


Empty Activity로 지정해 줍니다. 그리고 Next를 눌러줍니다.




Generate Layout File은 체크 해제 하겠습니다.


(필요 없을 것 같네요)


그리고 Finish를 눌러 세팅을 완료합니다.




프로젝트가 생성되었습니다.


이제 할 일은 Unity에서 사용할 수 있도록 classes.jar를 추가해야 합니다.


최상위 app에서 마우스 오른쪽을 눌러서 Open Module Settings를 들어갑니다.


(메뉴를 통해서도 가능합니다)




그리고 Dependencies 탭으로 이동하고, 


우측에 + 버튼을 눌른 후 File dependency를 선택합니다.




그럼 다음과 같은 화면을 보실 수 있습니다.


libs를 선택하면 상위에 경로가 나타나는데,  복사를 해 둡니다.


그리고 윈도우 탐색기(단축키 : 윈도우 + E)로 들어가서 


경로를 복사해 해당 폴더를 활성화 해 둡니다.




이제 유니티가 가지고 있는 classes.jar 파일을 


좀전에 열어둔 폴더로 옮겨야 합니다.


일반적으로 설치를 하셨다면 다음 그림에 보이는 경로에 있는 것입니다.




복사를 해서 아까 열어둔 폴더로 


classes.jar 파일을 복사합니다.




그리고 화면을 보시면 방금 추가한 파일이 나타납니다.


OK를 눌러줍니다.




잘 들어갔는지 확인을 하고 


OK를 눌러줍니다.




이제 불필요한 파일들을 지우겠습니다.


프로젝트쪽을 보시면 아래와 같이 test라는 것들이있습니다.


불필요 하므로 모두 삭제하겠습니다.




이제 유니티에서 호출할 테스트 코드를 작성하겠습니다.


MainActivity.java 파일로 들어갑니다.


우리는 UnityPlayerActivity를 상속 받아야 합니다.  다음 그림처럼 상속을 받아 줍니다.


그리고 static함수와 일반 함수를 호출 하는 함수들을 만들었습니다.



< 코드 >


 package com.test.plugintest;


import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {
// Call Static function
public static int GetStaticInt(int a)
{
return a + a;
}

public static String GetStaticString(String str)
{
return "Static GetString() : " + str;
}

public int GetInt(int a)
{
return a + a;
}

public String GetString(String str)
{
return "GetString() : " + str;
}
}



함수추가까지 완료되었습니다.


이제 남은일은 지금까지 만들었던 것들을 


jar 파일로 만들어서 유니티 쪽에 넣어주는 일입니다.


Gradle Scripts를 보시면 build.gradle(Module:app)이 있습니다. 더블클릭을 합니다.


그러면 다음과 같은 코드들을 볼 수 있습니다.



< 코드 >


apply plugin: 'com.android.library'

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"

defaultConfig {
//applicationId "com.test.plugintest"
minSdkVersion 10
targetSdkVersion 23
// versionCode 1
// versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile files('libs/classes.jar')
}

task deleteObjectJar(type: Delete){
delete 'release/AndroidPlugin.jar'
}

task exportJar(type: Copy){
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'AndroidPlugin.jar')
}

exportJar.dependsOn(deleteObjectJar, build)



그 코드들을 다음처럼 수정합니다.

(참고 : http://www.thegamecontriver.com/2015/04/android-plugin-unity-android-studio.html)




모두 작성이 되었으면, 메뉴에 Build ->Clean Project를 해 줍니다.




그리고 Gradle projects를 보시면 app->Tasks->other 쪽에


exportJar가 보일 것입니다.(좀전에 Gradle에 선언한 이름)




더블 클릭을 하시게 되면, 


Jar파일을 만드는 로그를 보실 수 있습니다.




확인을 위해 Project에서 app을 선택하고, 


우측 클릭을 하고 Show in Explorer를 선택합니다.




그리고 프로젝트 폴더에 app/release를 가시면 


방금 생성한 Jar파일이 보이실 것입니다.



여기까지 Android Studio를 통해 Jar파일 만드는 법을 하였습니다.


다음에는 실제 Jar파일을 읽어들여 유니티와 통신하는 방법을 포스팅 하겠습니다.


질문 있으시면 댓글 달아주세요.


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



- 유니티 버전 : 5.3.4f -



유니티3D 에디터(Editor) 캐시 삭제하기(Clean Cache)


어셋번들 매니저를 만들면서 테스트 하는데, 


단축키로 캐시삭제(Caching.CleanCache)를 하는데 불편함을 느껴서


에디터로 옮겼습니다.


*참고 : 캐시 삭제하는 함수는 Caching.CleanCache()입니다.


1분 작업량에 비해 많이 편하네요. 


우선 메뉴가 잘 만들어 졌는지 확인을 하겠습니다.


CleanCache라고 제가 만들어논 메뉴가 보이네요.




메뉴를 선택해보니 


오류없이 삭제되었다는 알림이 나왔습니다.




이제 정말 캐시가 삭제되었는지 확인을 해봐야 겠네요.


참고로 저는 지금 임시 UI로 


패치시스템을 만들고 있는 중입니다. (아주 간단하게..)


게임 실행을 해보니 13개 파일 받을게 있네요.




잘 받아지는지도 확인 해 보겠습니다.


13개가 차례대로 잘 받아집니다.




< 에디터 코드 >

using UnityEngine;
using UnityEditor;
using System.Collections;

public class PedtClearCaching {

    [MenuItem("Util/CleanCache")]
    public static void CleanCache()
    {
        if(Caching.CleanCache())
        {
            EditorUtility.DisplayDialog("알림", "캐시가 삭제되었습니다.", "확인");
        }
        else
        {
            EditorUtility.DisplayDialog("오류", "캐시 삭제에 실패했습니다.", "확인");
        }
    }
}


성공여부에 따라 팝업을 하나 띄워두었습니다.


Caching.CleanCache가 실패하는 경우는 


캐시를 사용하고 있을 때 입니다. 


혹시 실패가 뜬다면 유니티를 다시 껐다가 다시 켜보세요.


도움되셨길 바랍니다.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



- 유니티 버전 : 5.3.4f -



니티3D 에디터(Editor) 하위 폴더 순회하기(Recursion)


특정 폴더가 있고 그 하위 게임오브젝트에 어떠한 스크립트를 추가 할 일이 생겼습니다.


그런데 너무 많다보니 수작업으로는 안되겠더라구요.


그래서 에디터를 이용해서 추가하였습니다.


(실제 코드는 아래쪽에 작성하겠습니다.)


상단 메뉴로 Util을 만들고 하위에 두개의 메뉴를 만들었습니다.


하나는 스크립트 붙이는거, 다른 하나는 스크립트 제거하는거.




아래 그림에 있는 설명처럼 루트 폴더를 선택하고, 메뉴를 통해 스크립트를 붙여주면, 


프리팹 게임오브젝트에만 스크립트가 붙는걸 볼 수 있습니다.




다시 루트에서 제거하기 메뉴를 누르면


스크립트가 제거되는 걸 볼 수 있습니다.



< 에디터 코드 >


using UnityEditor;
using UnityEngine;
using System.Collections;
using System.IO;

public class PedtAutoAttachScript : Editor{
    [MenuItem("Util/AttachReApplyShaders")]
    public static void AttachReApplyShaders()
    {
        Object[] selectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);

        foreach(Object obj in selectedAsset)
        {            
            GameObject gObj = obj as GameObject;
            if (gObj != null)
            {
                string str = AssetDatabase.GetAssetPath(gObj);
                // Skip FBX 
                string strExtension = Path.GetExtension(str);
                Debug.Log(strExtension);
                if (strExtension.ToLower().CompareTo(".prefab") == 0)
                {
                    // 이미 추가 되어있는지 검사.
                    PcAutoAttatch script = gObj.GetComponent();
                    if(script == null)
                    {
                        // 없으면 추가.
                        gObj.AddComponent();
                        Debug.Log("Asset name : " + obj.name + " Type : " + obj.GetType());
                    }                    
                }                
            }
        }
    }

    [MenuItem("Util/RemoveReApplyShaders")]
    public static void RemoveReApplyShaders()
    {
        Object[] selectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);

        foreach (Object obj in selectedAsset)
        {            
            GameObject gObj = obj as GameObject;
            if (gObj != null)
            {               
                PcAutoAttatch script = gObj.GetComponent();
                if (script != null)
                {
                    Debug.Log("Asset name : " + obj.name + " Type : " + obj.GetType());
                    DestroyImmediate(script, true);
                }
            }
        }
    }
	
}


에디터를 통해 자동화가 된다면 최대한 사용해야겠죠?


도움 되셨길 바랍니다.



+ Recent posts