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


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

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

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




엑셀 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