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


모바일 게임 카카오 원(ONE)

* 쿠폰은 하단에 있습니다.


아는 분이 추천해줘서 카카오에서 나온 원(ONE)이라는 게임을 해보았습니다.


초반에 검색이 계산 안되어서 한참 애먹었습니다.




이번에도 여캐를 선택했습니다.


그래픽을 보면 요즘나온 게임같지가 않네요.


약간 구식(?)의 게임 같은 느낌입니다.




카카오 게임 원(ONE)은 장비 등급이 좀 특이합니다.


일반->영웅->전설->신화->고대->무적


종류가 참 많습니다.


아래는 가방관리(인벤토리)입니다.



다른게임과 확 차이는 없어보입니다.


상세보기를 눌러 확인이 가능합니다. 저의 경우 치명쪽으로 갈 계획입니다.




아이템을 누르면 양쪽으로 착용하고 있는 템과 비교해 줍니다.


전투력이 높더라도 옵션이 더 좋으면 그걸 차는게 낫겠죠.


저는 아직 신화템(좋아보이지만 중간급의)을 착용하고 있습니다.


이번주에는 고대무기를 만들 계획입니다.




강화시스템은 편리하게 되어있습니다.


재료를 자동으로 선택할수가 있으니까요.


무기 강화는 무기나 강화석이 필요하고, 


방어구는 방어구나 강화석이 필요합니다. (강화석은 탐사를 통해얻을 수 있습니다)




자동 선택을 하게 되면 저렇게 자동으로 들어가집니다.


정말 편한 기능입니다.




강화는 20강까지 있습니다. 20강 이후에는 승급이나 합성을 통해서 


다음 등급의 무기로 성장됩니다.




스킬은 아래처럼 5종류가 있는데 


저의 경우 피해량 증가가 가장 좋은것 같습니다.




길드는 길드 상점을 제외하고는 잘 모르겠네요.


길드에 들어오면 채팅이 있지만


(비활동길드라서?) 조용합니다. 




활동을(모험돌고) 하게되면 길드 공로포인트가 쌓이는데


길드상점에서 포인트를 사용하여 구입할 수 있습니다.




그리고 상점(일반상점)을 가게 되면, 매일 5번 무료뽑기가 있습니다.


이건 가능하면 꼭 해야겠습니다.




상점에 왔으니 10회 뽑기를 한번 해보겠습니다.


한번 하는데 300캐쉬가 들어가지만, 신화등급 하나 준다니까..


잘하면 고대가 나올수도 있으니까..


꽝입니다. 신화한개 나왔네요. 


캐쉬 모이면 한번더 해보렵니다.



탐사는 캐쉬, 강화석, 장비,장신구 등 가장 중요한 컨텐츠 같습니다.


좋은 점은 캐릭터 중 사용하지 않는 캐릭터로 탐사를 시킬수 있다는 점입니다.


그런데 그 캐릭터가 해당 챕터를 클리어 해야가능 하다는점..


그리고 아이템 강화하는데 강화석이 정말 많이 필요한데


탐사를 하게 되면 그래도 좀 주니까 꼭 필요한 요소입니다.




이렇게 영웅단계(저는 현재 영웅)에 있으면 획득 가능 아이템에


신화까지 있습니다. (그 전에는 전설입니다)


그리고 수호패스권을 사용하여 탐사를 즉시완료할 수 있습니다.




즉시완료를 하면 이렇게 보상이 들어오지요.




습격이라는게 있는데, 적이 탐사하고있는 아이템을 약탈할 수 있습니다.




다른대상찾기를 계속해서 좋은게 있으면 그때 하시면 됩니다.



그 외에 요일던전 등이 있는데 제 목표는 고대무기라서


다른게 잘 눈에 안들어오네요. 


그래도 제가 약간 좋아하는 그래픽이라서 할만 하네요.


시간 되시면 해보시길 바랍니다.


쿠폰 3384y3c8ydc84yf7 (캐쉬 100개입니다)


'게임' 카테고리의 다른 글

[게임] 커스텀  (0) 2016.09.18
[게임] 세븐나이츠 (쿠폰)  (5) 2016.07.10
[게임] 로스트 킹덤(Part II)  (0) 2016.06.02
[게임] 로스트 킹덤(Part I)  (0) 2016.06.02
[게임] 드래곤가드S (쿠폰)  (0) 2016.06.02
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 크기의 광고 코드만 넣을 수 있습니다.



[알고리즘] 선형검색(linear search)


선형검색(탐색)은 주어진 데이터에서 앞에서부터 순차적으로 


원하는 값을 찾는 방식입니다.


그렇기 때문에 시간복잡도는 O(n)이 됩니다.


구현이 매우 간단하지만, 


많은 데이터에서 검색을 하기에는 좀 부담이 되는 알고리즘 입니다.


데이터가 많을 때에는 이진이나 헤시 탐색등(logN)을 이용하는게 좋습니다.


< [5, 2, 13, 1, 8] 에서 1을 검색하는 과정 >



< 선형검색 코드 >

#include 
using namespace std;

// Using while
int linearSearch(int arr[], int length, int target)
{
	int nIndex = 0;
	while(nIndex < length)
	{
		if(arr[nIndex] == target)
			return arr[nIndex];
		nIndex++;
	}

	return -1;
}

int linearSearchWithFor(int arr[], int length, int target)
{
	for(int nIndex = 0; nIndex < length; nIndex++)
	{
		if(arr[nIndex] == target) return arr[nIndex];
	}

	return -1;
}

int main()
{	
	int arr[] = {5, 2, 13, 1, 8, 55, 29, 33};
	int target = 33;

	int nFound = linearSearch(arr, 8, target);

	if(nFound >= 0)
	{
		cout << "Found!!" << endl;
	}
	else
	{
		cout << "Not found!!" << endl;
	}

	return 0;
}



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



모바일 게임 로스트 킹덤(Part II)


인벤토리 화면 입니다.


운이 없는지 좋은 아이템이 잘 안나오네요.


넷마블 게임의 레이븐 이후로 


대부분 Full 3D 게임의 인벤토리가 비슷합니다.


아이템 화면도 그렇구요.


< 가방 >


우측 가방에 보이는 선택 분해를 하게 되면


다음처럼 재료를 얻을 수 있습니다.


주괴는 아이템을 강화할 때 사용하지요.


영웅 등급 이상부터는 랜덤으로 추가 재료가 나옵니다.


< 아이템 분해 >


그리고 원하는 레벨만 선택할 수 있도록


필터 기능도 있습니다. 이 기능은 정말 잘 만들었다고 생각드네요.



아이템을 눌러보시면 이렇게 정보창이 나타납니다.


무기로 설명을 드리자면


공격력과, 옵션 그리고 아이템 타입을 변경할 수 있습니다.


아이템 타입은 "분노의", "활력의", "길가메시의" 와 같은


아이템 이름 앞에붙는 것입니다.


그에 따른 효과가 달라집니다.


"길가메시의" 가 가장 좋다고 해서 저도 시도를 해보려고 합니다.


(사실 전에도 한 10번했네요)


< 아이템 정보창 >


마법 재부여권이 아이템 타입을 변경할 수 있도록 하는 건데, 


없을 경우 500 수정이 필요합니다.


한장이 있으니 한번 해보도록 하겠습니다.


< 마법부여(아이템 타입변경) >


저항이 나왔네요. 다시 해야겠네요.


이벤엔 활력이 나왔네요.


길가메시 얻고 싶은데 안나옵니다.


여기가 일반적인 모험의 월드맵입니다.


총 18장(챕터)까지 있습니다.


< 일반 모험 월드맵>


좌측 상단에 퀘스트를 눌러보면


현재 챕터에 대한 퀘스트를 확인할 수 있습니다.


< 챕터 퀘스트 >


일반 모험을 모두 클리어 하게 되면 


정예 스테이지가 활성화가 됩니다.


정예 스테이지에서는 골드 및 재료들을 획득할 수 있습니다.


올라갈 수록 좋은 등급의 재료를 획득할 수 있습니다.


< 정예 챕터>


아래 보이는 그림은 도전 모드에 관련된 컨텐츠들 입니다.


로스트 킹덤은 할거리가 많습니다.


< 도전 >


레이드를 보시면 다음처럼 3종류(한개는 업데이트 항목)가 있습니다.


캐릭터 레벨에 따라 오픈되는 시점이 달라집니다.


마지막 레이드인 슈라트 에서는 신화템도 나옵니다. 


< 레이드 메인화면 >


레이드 입장을 하게 되면 대기화면이 나오고


사람들과 매칭해서 시작이 됩니다. 물론 초대도 할 수 있습니다.(저는 자동매칭)


< 레이드 로비화면 >


아래 보이는 몬스터가 레이드 몬스터 입니다.


< 레이드 전투 >


저같은 경우 (약하기 때문에) 몇대 맞으면 죽습니다.


그래서 슈라트가 스킬을 사용할 때 저는 구르기를 해서 막 피해줘야 하죠.


슈라트가 피가없을 때 레이저(?) 같은걸 돌리는데 그게 정말 아파요.



레이드가 끝나고 나면 보상을 주는데, 


기여도가 너무 낮으면 받을 수가 없습니다. 


( 이 화면에서는 제가 금방 죽어서 기여도가 8밖에 안되네요)


< 레이드 보상화면 >


마족의 탑은 한층 한층 클리어 하는곳입니다.


클리어 여부에 따라 랭킹을 먹이고 그에 따른 보상을 줍니다.


< 마족의 탑 >


리그전은 말 그대로 1:1 PVP입니다.


이 또한 순위에 따라 보상이 주어집니다.


< 리그전 >


심연의 던전은 다른 유저들과 함 께 타워(?)를 지키는 겁니다.


< 심연이의 던전 >


일일던전은 하루 1회 밖에 못합니다.


요일던전은 요일별로 다른 보상을 주고, 


골드던전은 말 그대로 골드를 줍니다. (근데 생각보다 적게주네요)


< 일일 던전 >


난투장은 여러명이 들어와서 PVP를 하는 것입니다.


시간내에 많은 킬을 해서 점수를 올리는게 좋습니다.


< 난투장 >


1달간 플레이를 했네요. 근데 생각보다 컨텐츠들을 제대로 못해봤습니다.


그래도 재미있게 했네요. 특히 레이드에서.


코어한 것 좋아하시면 해보셔도 좋겠네요.


'게임' 카테고리의 다른 글

[게임] 커스텀  (0) 2016.09.18
[게임] 세븐나이츠 (쿠폰)  (5) 2016.07.10
모바일 게임 카카오 원(ONE)[쿠폰포함]  (0) 2016.06.14
[게임] 로스트 킹덤(Part I)  (0) 2016.06.02
[게임] 드래곤가드S (쿠폰)  (0) 2016.06.02
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



모바일 게임 로스트 킹덤(Part I)


한동안 재미있게 했던 게임입니다.


원래는 오래전에 나왔어야 할 게임이었는데


좀 연기되었었죠. 


플레이를 해보니 좀 코어하면서 재미있었습니다.


< 초기 화면 >



로스트킹덤에 아크메이지가 나왔을 때 시작을 했습니다.


신규 캐릭은 항상 초반에 좀 혜택이 있더라구요.


< 캐릭터 선택 화면 >



로스트킹덤은 게임 플레이를 하지않아도


휴식 경험치를 통해 보상을 받습니다.


만랩(lv 55) 전까지는 경험치를 받고,


만랩에는 골드 획득을 합니다.


< 휴식경험치 >



마을화면인데 엄청 느립니다. (저는 아이폰6+사용중)


마을에서 할 수 있는건 타 유저들 정보 보기밖에 없는데..


타 유저들이 마을에 동시에 등장하니 무지 버벅대네요.


< 로비(마을) 화면 >



타 유저의 캠프로 가면 이렇게 나옵니다.


디테일이라고 해야하나? 


디테일은 좋은데 너무 느리네요.


< 유저의 정보를 볼 수 있는 캠프 >



길드에 들어가면 출석해서 보상을 받을 수 있습니다.


그외에는 게시판이 있습니다.


글쓰고 답하는 커뮤니티 기능입니다.


< 길드 >



스킬의 카테고리는 총 6개가 있는데 


첫번째, 두번째가 액티브 스킬에 관련된 거고, 


마지막꺼는 패시브구요 그 외에것들은 특수 상황일 때 사용합니다.


저는 액티브쪽에만 투자했네요.


< 스킬 >



두번째액티브도 공격 관련된것만 선택했습니다.




패시브 또한 공격관련된것만 했습니다.




요즘 모바일 게임과 마찬가지로 


임무에는 일일, 주간, 이벤트 퀘스트가 있습니다.


보상이 있으니까 매일 해야 손해를 안봅니다.


< 임무 >



로스트킹덤이 정말 코어하다는 것 중에 하나가 


제작 시스템 입니다. 


재료들은 필드와 보상, 획득한 아이템을 분해 하면 획득할 수 있습니다.


분해, 제작이 들어가면 정말 코어해지죠.


< 제작 >



궁극장비가 있는데 저는 여기까지는 못했네요.


옆에 설명 처럼 50레벨 이상 신화 +10 이상 장비가 필요합니다.


저에게는 먼 이야기네요.




좀전에 제작을 말했듯이 재료 또한 재작가능합니다.


정말 게임이 코어합니다.




임무와 비슷한 개념으로 업적이 있습니다.


< 업적 >



로스트 킹덤에는 칭호라는 타이틀이 있는데 


몬스터를 많이 잡거나, 레이드를 많이 뛴다거나 등 행위를 하면 


획득할 수 있습니다. 그러면 버프효과가 발생합니다.


중요한 요소중에 하나입니다.


< 칭호 >



업적을 수행하게 되면 작위포인트를 얻을 수 있는데


그 작위포인트를 모아서 작위 등급을 올릴 수 있습니다.


전투중에 소환할 수 있는 용병이 있는데


작위에 따라 용병의 레벨이 높아지게 됩니다. (전 궁수를 사용합니다.)


< 작위 >



왕국에서 마지막으로 킹덤스톤 이라는게 존재합니다.


킹덤스톤은 능력치를 올려주는 버프 역할을 하는데


최초 활성을 시키려면 각 킹덤스톤에 맞는 레벨의 장비를 신화까지 만들어서


재료로 바쳐야합니다. 쉽지 않지요.


오픈 후에는 장신구를 분해해서 나오는 재료로 레벨업을 할 수 있습니다.


< 킹덤스톤 >


너무 길어져서 파트 2개로 나누겠습니다.


하드코어한 게임 좋아하신 분들은 한번 해보시길 바랍니다.


'게임' 카테고리의 다른 글

[게임] 커스텀  (0) 2016.09.18
[게임] 세븐나이츠 (쿠폰)  (5) 2016.07.10
모바일 게임 카카오 원(ONE)[쿠폰포함]  (0) 2016.06.14
[게임] 로스트 킹덤(Part II)  (0) 2016.06.02
[게임] 드래곤가드S (쿠폰)  (0) 2016.06.02
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



모바일 게임 드래곤가드S(쿠폰)


쿠폰 사용하면 100만원 상당 보상빵야라고 합니다.


(쿠폰은 하단에 쓰겠습니다)



요즘 할 게임이 없어서 게임을 찾는도중


힐러 업데이트가 되었다고 


쿠폰 준다고 해서 한번 설치 해봤습니다.


새로운 캐릭터라니 힐러를 선택했네요. 


딱 30분 정도 플레이를 했습니다.


드래곤가드S 저에게는 잘 안맞나 봅니다. 


쿠폰 사용해서 해보려다가 그냥 나눔하려고 합니다.



플레이를 많이 안해봐서 잘 모르겠는데


이미지들을 보니 재밌어 보였습니다.


그런데 저와는 거리가 좀 먼 게임인듯 하네요.



레벨업을 좀 많이 해서


길드전도 해보고 싶었습니다. (실패)


그리고 던전에 들어가서도 해보고 싶었네요.




드래곤가드S를 보면 


완전 PC 게임이라는 생각이 듭니다.


실시간 PVP, 레이드 등등. 



별로 플레이를 안해서 장/단점을 쓰기도 힘드네요.


저는 플레이를 하지 않으니


하실분들은 쿠폰 사용하세요. 


(안드로이드만 되는걸로 알고있습니다)



쿠폰 : BFA46D7E07F0449C


쿠폰 사용 방법 


메인로비 우측 상단 '시스템' > 쿠폰 > 쿠폰 입력란에 쿠폰코드 등록.


'게임' 카테고리의 다른 글

[게임] 커스텀  (0) 2016.09.18
[게임] 세븐나이츠 (쿠폰)  (5) 2016.07.10
모바일 게임 카카오 원(ONE)[쿠폰포함]  (0) 2016.06.14
[게임] 로스트 킹덤(Part II)  (0) 2016.06.02
[게임] 로스트 킹덤(Part I)  (0) 2016.06.02
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.




엑셀 IF와 IF ELSE 사용하기

(Office 2013 기준)



IF 는 "만약 ~ 하다면.." 이죠.


ELSE는 "그 외에 것." 입니다.


예를 들어 볼게요. (뜬금없는 영어 양해부탁합니다.)


< If >


"If I were a bird, I could fly to you."


("만약 내가 새라면 너에게 날아갈꺼야.")



< else >


"Are you ready to order?"


("주문 하시겠어요?")


"Coffe, plz."

("커피 주세요.")


"Anything else?"
("커피 외에 또 있나요?")




한번 예를 들어보았는데, 이상하네요.ㅎㅎ



이제 엑셀에서 IF와 IF..ELSE를 사용해보겠습니다.


사실 엑셀에는 ELSE가 없습니다. 


IF를 이용해서 ELSE를 만드는겁니다.



RAND 포스팅 에서 했던걸 가져다 쓰겠습니다.


아래 보이시는 것처럼 체력에 따라 체력기준에 데이터를 입력하려합니다.





IF의 구문은 다음과 같습니다.


= IF(조건, 참일 때 값, 거짓일 때 값)


여기에서 체력이 0부터 500이면 "500 이하" 라고 표시하고, 


그 외의 값은 500 "500 초과" 라고 표시할 예정입니다.


(아래 그림에 501~1000이라고 되어있는건 


RAND 포스팅 데이터의 MAX 값이1000이므로 그렇습니다.)





체력의 값을 조건으로 사용하므로, 


=IF(C2,....) 가 우선 되겠죠.





500이하 이므로, 


=IF(C2 <= 500,....) 라고 칩니다.





그리고 참일때와 거짓일 때의 값을 입력해 줍니다.





바로 결과가나왔습니다.


값들도 잘 나왔네요.





IF문을 했으니, 이제 IF..ELSE를 하겠습니다.


엑셀에서 IF.. ELSE는 다음처럼 하셔야 합니다.


IF(조건, "참", IF(조건,"참", "거짓"))


우선 300이하 일때에는 "하" 라는 값을 넣기 위해


=IF(C2 <= 300,  을 먼저 합니다.





그 외의 값들은 300보다 큰 값들이겠죠.


그 큰 값들에 다시 조건을 넣습니다.


=IF(C2 <= 300, "하", IF(C2 <= 600,..


그러면 "거짓" 일 때의 값 내에서 다시 조건검사를 하게 됩니다.





그래서 다음그림처럼 조건이 들어가게 됩니다.





값을 보면 잘 나오는걸 확인할 수 있습니다.




글이 좀 길어서 헷갈렸을 수도 있겠네요.


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


IF(조건, "참", "거짓) 입니다.


IF.. ELSE 가 있을 경우는


IF(조건, "참", IF(조건, "참", "거짓"))


IF.. ELSE IF... ELSE IF... ELSE.. 가 되면 어떻게 될까요?


IF(조건, "참", IF(조건,"참", IF(조건, "참")......... 


도움 되셨기 바랍니다.



+ Recent posts