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 크기의 광고 코드만 넣을 수 있습니다.


유니티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 크기의 광고 코드만 넣을 수 있습니다.


- NGUI 버전 : 3.9.8 -


NGUI 토글버튼 기초


게임을 구현하다 보면, 토글 버튼이라던가 라디오버튼이 필요할 때가 있습니다.


이를 위해 NGUI에서는 UIToggle이라는 컴포넌트를 제공합니다.


이 기능에 대해 간단하게 알아보고, 다음 포스팅에서 


제어할 수 있게 구현하도록 하겠습니다.



* 포스팅에 사용되는 이미지는 유료라서 공유가 힘듭니다. 양해바랍니다.


우선 아래 그림처럼 배치를 하도록 합니다.  


ToggleA(Gray)는 빈 게임오브젝트 이며, 자식으로 버튼들이 들어갑니다.


NGUI에서 기본 뼈대 만드는 법과, Button 만드는 법은 다음을 참고하세요.


[NGUI] 스프라이트(SPRITE)


[NGUI] 버튼과 레이블




이제 ToggleA(Gray)게임 오브젝트에 


UIToggle과 UIToggleComponents를 추가합니다.


(나머지도 동일하게 추가합니다)


Box Collider넣고 Size 설정하는거 잊지 마시기 바랍니다.


그리고 아래 설명에 나온것처럼 세팅을 해 줍니다.




실제 기능은 완료가 되었습니다. 아주 간단하죠.


이제 확인을 해보고 위해서 레이블 하나를 추가하겠습니다.


[NGUI] 버튼과 레이블 참고




ToggleHandler라는 스크립트를 하나 만들고, 


다음 처럼 코딩하겠습니다. (설명은 주석으로 하겠습니다)



< ToggleHandler.cs 코드 >


using UnityEngine;
using System.Collections;

public class ToggleHandler : MonoBehaviour {

    // 어떤 버튼이 활성화 되었는지 표시하기 위함.
    public UILabel m_lblMessage;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    // 토글 버튼이 바뀔 때 발생하는 이벤트
    public void OnChangeToggle()
    {
        // 현재 상태가 변한 토글버튼을 가져옵니다.
        UIToggle current = UIToggle.current;
        // 우리는 활성화 된 경우만 처리할 예정이므로,
        // 활성화 된것(value가 true)이 아닌경우(false인 경우) return합니다.
        if (current.value == false) return;
        // 확인을 위해 메시지를 뿌립니다.
        m_lblMessage.text = current.name;
    }
}



코드 작성이 완료되었으면, 


ToggleHandler.cs를 UI Root 게임 오브젝트에 넣어줍니다.




메시지를 봐야하므로, Message를 연결시켜줍니다.




마지막 단계만 남았습니다.


ToggleA(Gray)를 선택하보면, 아까 넣어둔 UIToggle이 보입니다.


거기에 보면 On Value Change라는게 보이는데, 


상태가 변하면 발생하는 이벤트 입니다.


우리가 만든 함수를 거기에 등록하도록 하겠습니다.




이제 실행을 하고 버튼을 눌러보면, 다음과 같은 결과를 볼 수 있습니다.



< 결과 >



기본 기능은 간단하지만, 


제어를 하려면 수작업이 좀 필요합니다.


다음 포스팅에는 제어하는 방법에 대해 설명하도록 하겠습니다.


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



'게임 프로그래밍 > NGUI' 카테고리의 다른 글

[NGUI] 토글버튼(Toggle) 제어  (0) 2016.07.13
[NGUI] 버튼과 레이블  (0) 2016.06.07
[NGUI]스프라이트(SPRITE)  (0) 2016.05.26
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

C# CSV 파일 읽기(CSV Reader)



원래 XML을 사용하려고 했는데, 


읽는 속도가 CSV가 빠를것 같아서 간단히 구현을 하려합니다.


다음과 같은 데이터로 테스트를 하겠습니다.


ID앞에 #을 붙인 이유는 첫 라인이 키라는것을 명시하기 위함입니다.


* 파싱할 때 첫 라인을 키로 잡아도 됩니다.




만든 테이블을 CSV로 저장을 하였다면, 


인코딩을 UTF8로 바꿔주셔야 합니다.


그래야 모든 언어에서 오류없이 작동합니다.


자동 저장은 http://slway000.tistory.com/17 를 참고하세요.


우선 수작업으로 하기 위해, 메모장으로 열어서 다음처럼


인코딩을 UTF-8로 바꿔줍니다.




다음은 C#으로 작성한 코드 입니다. 


(테스트 코드를 만들고 나중에 유니티에 적용할 예정입니다.)


파일을 읽어들여 한라인씩 읽어서 


키와 값들을 구분시켜 처리하도록 합니다.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace CSVParse
{
    class Program
    {
        static void Main(string[] args)
        {
            string strFile= "testcsv.csv";

            using (FileStream fs = new FileStream(strFile, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.UTF8, false))
                {
                    string strLineValue = null;
                    string[] keys = null;
                    string[] values = null;

                    while ((strLineValue = sr.ReadLine()) != null)
                    {
                        // Must not be empty.
                        if (string.IsNullOrEmpty(strLineValue)) return;

                        if (strLineValue.Substring(0, 1).Equals("#"))
                        {
                            keys = strLineValue.Split(',');

                            keys[0] = keys[0].Replace("#", "");

                            Console.Write("Key : ");
                            // Output
                            for (int nIndex = 0; nIndex < keys.Length; nIndex++)
                            {
                                Console.Write(keys[nIndex]);
                                if (nIndex != keys.Length - 1)
                                    Console.Write(", ");
                            }

                            Console.WriteLine();

                            continue;
                        }

                        values = strLineValue.Split(',');

                        Console.Write("Value : ");
                        // Output
                        for (int nIndex = 0; nIndex < values.Length; nIndex++)
                        {
                            Console.Write(values[nIndex]);
                            if (nIndex != values.Length - 1)
                                Console.Write(", ");
                        }

                        Console.WriteLine();
                    }
                }                
            }            
        }
    }
}



결과화면입니다.




아주 간단한 예제이기 떄문에 실제 데이터 파싱할 경우


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



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 크기의 광고 코드만 넣을 수 있습니다.

패키지 파일입니다. 다운받으세요^^

pack.unitypackage


[ 유니티허브 질문 ] 유니티 리소스 로드 하기. (cho3**** 님)



다음 순서를 통해 설명드리겠습니다.

1. 프리팹 만들기.

2. 스크립트 만들기.

3. 스크립트 등록하기.

4. 스크립트를 통해 로드하기.

5. 테스트.



우선 테스트를 할 프리팹 하나를 만들도록 하겠습니다.


큐브를 하나 만들어서 사용할게요.


아래 그림에 나타난 방법중 하나를 선택하여 하시면 되십니다.




그러면 큐브가 하나 만들어 졌습니다.


이제 이 큐브를 프리팹으로 만들도록 하겠습니다.




Project 쪽을 모시면 Assets라는 폴더만 있을것입니다.


그 하위로 마우스 오른쪽 눌러서 폴더를 만드는데


이름을 꼭!!! Resources 라고 해주셔야 합니다.


(이유가 궁금하시면 댓글달아주세요 ㅎㅎ)




이제 조금전에 만든 Cube를 Resources 폴더 내에 


쭉 끌어다 놓습니다.


그러면 Hierarchy쪽에 있는 Cube가 파란색으로 변합니다.


파란색이라는 건 프리팹이 되었다는걸 의미합니다.




이제 Hierarchy 쪽에 Cube를 지워줍니다.


그럼 다음 그림처럼 되었겠죠?




이제 스크립트를 만들어서 리소스를 로드하는 걸 하겠습니다.


우선 스크립트를 만들어야 합니다.


아래 그림의 방법중 하나를 골라서 스크립트를 만듭니다.




스크립트 이름은 LoadResource 라고 하겠습니다.


(스크립트는 어떤 폴더에 있건 상관없습니다.)




구현 코드 입니다. 코드에 주석을 달아두었으니 참고하시고


궁금한건 댓글 달아주세요. 


< LoadResource.cs 의 코드 >

using UnityEngine;
using System.Collections;

public class LoadResource : MonoBehaviour {

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
        // A 키를 눌러 확인하겠습니다.
	    if(Input.GetKeyDown(KeyCode.A))
        {
            // Resources 폴더에 있는 것중, Cube라는 프리팹(게임오브젝트)를
            // 로드합니다. 원본이 로드되는것입니다.
            GameObject gObjPrefab = Resources.Load("Cube") as GameObject;

            // 혹시 파일이 없을 수도 있으니 null체크(로드가 안되면 null입니다).
            if (gObjPrefab != null)
            {
                // Instantiate 함수는 게임오브젝트를 복사해서 생성하는 역할을 합니다.
                Instantiate(gObjPrefab);
            }
        }
	}
}



코드가 완성 되었으면, 이 코드가 작동할 수 있도록 해야합니다.


그러기 위해서는 Hierarchy에 있는 게임오브젝트에


추가가 되어야 합니다. 


다음 그림처럼 LoadResource 스크립트를 끌어다가 Main Camera에 넣어주세요.


( Main Camera 뿐 아니라 Directional Light에 넣으셔도 됩니다. )


아래 그림에 Inspector보이시나요?


거기에 LoadResource 가 추가된것이 보입니다.




모든 작업이 끝났습니다.


실행을 하면 아래 왼쪽 그림처럼 아무것도 없을 거에요.


그리고 A 키를 누르면 Cube(Clone)이 나타났을 것입니다.



최대한 자세히 설명했는데 이해가 되셨을지 모르겠네요.


궁금한건 언제든 물어보세요. 



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


리소스 폴더 내 파일 가져오기.


using UnityEngine;
using System.Collections;

public class LoadAllTest : MonoBehaviour {

	// Use this for initialization
	void Start () {

        //object[] obj = Resources.LoadAll("");     // Resources 폴더 내 모든 파일 가져오기
        object[] obj = Resources.LoadAll("Images"); // Resources/Images 폴더 내 모든파일 가져오기.
        for (int nIndex = 0; nIndex < obj.Length; nIndex++)
        {
            Debug.Log("Index : " + nIndex.ToString() + ", Object : " + obj[nIndex].ToString());
        }

    }
	
	// Update is called once per frame
	void Update () {
	
	}
}


모든 파일을 가져오니 타입이나 확장자를 통해서


구분을 하셔야 합니다 ㅎㅎ



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


조원희 님이 원하시는 소스.


(제가 이해한게 맞길 바래요)


using UnityEngine;
using System.Collections;

public class LoadResource : MonoBehaviour {

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
        // A 키를 눌러 확인하겠습니다.
	    if(Input.GetKeyDown(KeyCode.A))
        {
            GameObject cube = null;
            // Resources 폴더에 있는 것중, Cube라는 프리팹(게임오브젝트)를
            // 로드합니다. 원본이 로드되는것입니다.
            GameObject gObjPrefab = Resources.Load("Cube") as GameObject;

            // 혹시 파일이 없을 수도 있으니 null체크(로드가 안되면 null입니다).
            if (gObjPrefab != null)
            {
                // Instantiate 함수는 게임오브젝트를 복사해서 생성하는 역할을 합니다.
                cube = Instantiate(gObjPrefab);
            }

            // 모든 리소스 불러오기(Image 폴더내에 입니다)
            // 현재 Image 폴더내에는 Texture만 있으므로 분류처리 안할께요.
            // 분류처리(?)란 Image 폴더내에 프리팹이나 사운드 파일 등이 같이 있을 때에
            // 텍스쳐만 가져오도록 하는 것입니다. 
            // 궁금하시면 말씀하세요. 다시 알려드릴께요^^
            // 우런 아래처럼 LoadAll을 하시면 Image 폴더안에 있는
            // 모든 이미지들(사실은 오브젝트)이 배열이라는 걸로 저장됩니다.
            // [] <= 요게 배열.
            object[] arrObj = Resources.LoadAll("Images");

            // 그래서 배열에서 첫번째껄로(0부터 시작합니다) 세팅하도록 할께요.
            // 그리고 지금은 무조껀 텍스처라고 가정하므로 이렇게 형변환 이라는걸 해줘야 되요.
            Texture2D texture = arrObj[0] as Texture2D;
            // 텍스쳐(이미지)를 가져왔으니 큐브에 세팅~!.
            cube.GetComponent().material.mainTexture = texture;
            
        }
	}
}


* 소스에서 가장 아래 </Renderer> 이거는 삭제하세요.


* 소스 코드 올리는거에 약간 버그같은거? 가 있어서 ㅎㅎ


위쪽에서 스크립트 등록하는거 보셨죠?


그렇게 똑같이 등록해서


실행한 다음에 A 키 눌러보세요.


그러면 이렇게 세팅.



메일 주소 적어주세요. 


완성된 프로젝트 보내드릴께요.


(저는 버전 5.3.5 사용중입니다)


******* 실시간으로이미지 로딩하기 추가. ******


테스트 해보니 잘 되네요.


현재 테스트 용이므로, 실제 원하시는 기능은 다시 구현하셔야 되세요 ㅎㅎ

이미지는 여기꺼 : http://www.flaticon.com/packs


코드에 주석 달아두었습니다.



using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class LoadResources : MonoBehaviour {

    // 생성된 큐브를 화면내에 뿌리기 위해 최대치 지정.
    private readonly float MIN_X_POS = -8f;
    private readonly float MAX_X_POS = 8f;
    private readonly float MIN_Y_POS = -4f;
    private readonly float MAX_Y_POS = 4f;

    // 현재까지 만들어진 것 저장. 중복해서 생성하지 않기 위해 만듬.
    List m_lImageNames = new List();
    // 1초에 한번씩 검사.
    float m_fTimeChecker = 0f;
    // 큐브 프리팹.(한번 로드해 두고 복사해서 생성한다)-> 속도 위함.
    GameObject m_gObjCubePrefab;
	// Use this for initialization
	void Start () {
        m_gObjCubePrefab = Resources.Load("Cube") as GameObject;
        // 로드 실패할 경우를 대비하여 Null 체크 해본다.
        if (m_gObjCubePrefab == null)
        {
            Debug.LogError("Can not load cube!! Please check the path of the cube!");
        }

	}
	
	// Update is called once per frame
	void Update () {
        LoadImagesDynamically();
	}

    // 1초에 한번씩 검사해서 로드하지 않은 이미지들 로드해서 보여주기.
    // 큐브를 생성하여 이미지를 표시한다.
    private void LoadImagesDynamically()
    {
        // 큐브프리팹이 null이면 안된다!!
        if (m_gObjCubePrefab == null) return;

        // 경과 시간을 계산한다.
        m_fTimeChecker += Time.deltaTime;

        // 1초마다 생성.
        if (m_fTimeChecker >= 1f)
        {
            // 경과시간 초기화.
            m_fTimeChecker = 0f;

            // 우선 이미지들 로드 후 검사.
            object[] arrObj = Resources.LoadAll("Images");

            for(int nIndex =0 ;nIndex < arrObj.Length; nIndex++)
            {
                Texture2D texture = arrObj[nIndex] as Texture2D;

                if (texture != null)
                {
                    // 기존에 로드 했는지 검사 후 신규일 경우만 생성.
                    if (IsAlradyLoaded(texture.name) == false)
                    {
                        // 로드한 리스트에 이름 추가(중복 로드 피하기 위해서)
                        m_lImageNames.Add(texture.name);
                        // 새로 큐브 생성.
                        GameObject gObjNew = Instantiate(m_gObjCubePrefab) as GameObject;
                        // 큐브 위치 랜덤하게 잡고.
                        gObjNew.transform.localPosition = GetRandomPosition();
                        // 이미지 세팅하도록 한다.
                        gObjNew.GetComponent().material.mainTexture = texture;
                    }
                }
            }            
        }
    }

    // 기존에 이미 로드된 것인지 검사하는 함수
    // 이미 로드되었으면 true를 리턴한다. 그렇지 않으면 false 리턴.
    private bool IsAlradyLoaded(string _str)
    {
        for (int nIndex = 0; nIndex < m_lImageNames.Count; nIndex++)
        {
            if (m_lImageNames[nIndex] == _str)
                return true;
        }

        return false;
    }

    // 랜덤으로 위치 얻기.
    private Vector3 GetRandomPosition()
    {
        float x = Random.RandomRange(MIN_X_POS, MAX_X_POS);
        float y = Random.RandomRange(MIN_Y_POS, MAX_Y_POS);
        // z축은 하지 않을께요 ㅎㅎ

        return new Vector3(x, y, 0f);
    }
}


가장 아래 </renderer></string></string>은 지워주세요.




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




- NGUI 버전 : 3.9.8 -


NGUI 버튼과 레이블의 활용


간단한 사용법에 대해 포스팅 하도록 하겠습니다.


(아틀라스와 스프라이트 기초는 여기 에서 확인 하세요)


* 포스팅에 사용되는 이미지는 유료라서 공유드리기가 힘드네요. 양해부탁드립니다.



우선 가지고 계신 이미지로 다음처럼 배치를 하겠습니다.




버튼 A 자식으로 게임오브젝트를 하나 만들고,


거이에 UILabel하나를 추가하도록 합니다.


그리고 Depth는 50정도로 잡아줍니다.


( 스프라이트와 레이블의 뎁스는 분리시키는게 좋습니다. )


( 드로우콜이 덜 발생하는걸로 들은것 같네요. )




다음 화면처럼 UILabel 세팅이 되었다면, 


이제 버튼으로 다시 가서, Box Collider를 추가합니다.


( Box Collider가 있어야 클릭할 때 이벤트를 발생 시킬 수 있습니다. )


그리고 auto-adjust to match를 눌러줍니다. 그러면 Box Collider 사이즈가 동일하게 적용됩니다.




이제 버튼을 눌렀을 때 효과를 주려고 합니다.


일반 상태의 버튼이미지와, 마우스가 올라갔을 때 다른 이미지를 표시할 예정입니다.


Button 이라는 컴포넌트를 추가합니다.




NormalHover 그리고 Pressed 모두 흰색으로 변경시킵니다.


(색상을 넣으면 마우스 이벤트시(Hover, Pressed등) 버튼 색상이 변경됩니다)


그리고 Sprites에서 Normal 상태와 Hover상태의 이미지를 세팅해줍니다.




이제 마우스를 올렸을 때와 눌렀을 때 버튼 사이즈도 변경하려고 합니다.


Button Scale 컴포넌트를 추가합니다.


(기본 세팅값으로 두겠습니다)




버튼 B도 방금했던 작업들을 동일하게 적용시킵니다.


그리고 실행하면 다음처럼 동작할 것입니다.




버튼에 이벤트를 추가 하려고 합니다.


이벤트 발생 여부를 표시하기 위해 Label하나를 추가하겠습니다.


OverflowShirink Content로 하고 


좌측 빨간 네모처럼 사이즈를 맞춰줍니다.




이벤트를 발동 시키기 위해 스크립트를 하나 생성하겠습니다.


저는 ButtonTest.cs 라는 스크립트를 만들겠습니다.


< ButtonTest.cs >

using UnityEngine;
using System.Collections;

public class ButtonTest : MonoBehaviour {

    // 버튼 눌렀을 때 나타낼 메시지.
    public UILabel m_lblMessage;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    // 버튼 A를 클릭했을 때 발생하는 이벤트
    public void OnClickButtonA()
    {
        m_lblMessage.text = "A 버튼을 클릭하였습니다.\nA버튼은 회색입니다.";
    }

    // 버튼 B를 클릭했을 때 발생하는 이벤트
    public void OnClickButtonB()
    {
        m_lblMessage.text = "B 버튼을 클릭하였습니다.\nB버튼은 빨간색입니다.";
    }
}


이제 이 스크립트를 UI Root에 넣고


마지막에 만든 레이블(Text)를 연결해줍니다.




이제 버튼 이벤트를 연결해야 하므로, 버튼을 선택합니다.


그리고 UIButton 컴포넌트에 있는 OnClick에 UIRoot를 연결합니다.


그리고 보시면 좀전에 만든 OnClickButtonA 함수가 보일것입니다.


선택하도록 합니다.




버튼B도 마찬가지로 이벤트를 연결시켜 줍니다.


실행을 해 보시면 다음처럼 잘 작동 될 것입니다.




이제 TypewriterEffect 를 이용해서 레이블에 효과를 주겠습니다.


TypewriterEffect는 코드를 이용해서 추가하겠습니다.


< ButtonTest.cs 에 세번째 이벤트 추가 >

using UnityEngine;
using System.Collections;

public class ButtonTest : MonoBehaviour {

    // 버튼 눌렀을 때 나타낼 메시지.
    public UILabel m_lblMessage;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    // 버튼 A를 클릭했을 때 발생하는 이벤트
    public void OnClickButtonA()
    {
        m_lblMessage.text = "A 버튼을 클릭하였습니다.\nA버튼은 회색입니다.";
    }

    // 버튼 B를 클릭했을 때 발생하는 이벤트
    public void OnClickButtonB()
    {
        m_lblMessage.text = "B 버튼을 클릭하였습니다.\nB버튼은 빨간색입니다.";
    }


    // 레이블 효과
    public void OnClickButtonC()
    {
        // 효과를 나타낼 텍스트 추가.
        m_lblMessage.text = "동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세." +
                            "무궁화 삼천리 화려강산 대한사람 대한으로 길이 보전하세.";
        // 효과를 주는 컴포넌트를 추가한다.
        TypewriterEffect twe = m_lblMessage.gameObject.AddComponent();
        twe.ResetToBeginning();
    }
}



사진이라서 정확하게는 표현을 못하였지만, 


실행해 보시면 어떤 효과인지 아실 수 있을 것입니다.


typewriterEffect는 튜토리얼이나 대사창 등에 효과적으로 


이용하실 수 있습니다.



다음은 재사용 스크롤 뷰를 포스팅 하도록 하겠습니다.


도움되셨길 바랍니다.


'게임 프로그래밍 > NGUI' 카테고리의 다른 글

[NGUI] 토글버튼(Toggle) 제어  (0) 2016.07.13
[NGUI] 토글버튼(Toggle)  (0) 2016.07.02
[NGUI]스프라이트(SPRITE)  (0) 2016.05.26
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