근래에 새로운 프로젝트에 들어가는 바람에 강좌 업데이트가 안되서 죄송합니다.
모바일에서 3D게임이 조금씩 고급으로 치닫는 바람에 공부해야할게 너무나 많네요.

오늘은 간단히 Code로 Mesh를 생성해보겠습니다.

일단, Mesh라는 녀석을 정확히 한번 따져보겠습니다.
Mesh란 Wiki에 따르면 (http://en.wikipedia.org/wiki/Polygon_mesh) 이러합니다.

A polygon mesh is a collection of vertices, edges and faces that defines the shape of a polyhedral object in 3D computer graphics and solid modeling.

* 폴리곤 메쉬는 버티컬들과 엣지들과 면들을 3D컴퓨터 그래픽/솔리드모델링에서 사용하는 다면체의 모양의 집합이다.

뭐... 번역이 어려워서 글치 결국 폴리곤이라는 녀석을 모아 놓은게 폴리곤 메쉬 즉, 우리가 흔히 이야기하는 메쉬가 되겠습니다.

이럴때는 어려운 말 한마디 보다 다음의 Vertex-Vertex Meshes의 예를 한번 보죠.

* Vertex-Vertex Meshes의 예
사용자 삽입 이미지
점 9개가 보여서 하나의 육면체를 이루고 있습니다.
정확하게는 다음과 같이 구성되어 있습죠. 네네...
사용자 삽입 이미지


Vertex는 점입니다. 이 점들을 이은 선이 접선 또는 Edge하고 하고 이렇게 Edge가 보이면 면(Face)가 되고 Face가 2개 이상 모이면 면(Surface)가 됩니다. 다시 면들을 모으면 폴리곤 메쉬가 됩니다. (쉽죠?)

암튼 우리는 개발자니까(?)... 데이터구조에 관심을 가져봅시다.

첫 번째 예제를 보면 좌측에 Vertex List에 대한 데이터까지 상세하게 정의되어 있군요!
V0값은 Vector3좌표와 인접한 Vertex의 Index를 가지고 있습니다.

이제 이걸 기초로 메쉬 한번 만들어 봅시다.
물론 처음부터 육면체 만들자고 하면 서로 머리 복잡하니, Vertex 4개로 구성된 작은 4각형 메쉬를 만들겁니다.

먼저 빈 게임오브젝트 1개를 만들어 봅시다.
사용자 삽입 이미지
만들어진 빈 게임오브젝트에 Mesh Compoent인 Mesh Filter와 Mesh Renderer를 추가합니다.
사용자 삽입 이미지
- Mesh Filter는 Mesh의 데이터를 저장합니다.
- Mesh Renderer는 렌더링을 Mesh Filter에 있는 데이터로 렌더링을 담당하죠.

그리고 인식하기 쉽게 게임오브젝트의 이름을 "Mesh"라고 변경합니다.
아래의 예를 보면 Mesh Filter Components에는 "None (Mesh)"라고 되어 있는게 보이실 겁니다.

사용자 삽입 이미지
이제 여기 "Mesh Filter"에다가 데이터를 넣어 봅시다.

C# 스크립트를 하나 만들고 다음과 같이 코딩합니다.

using UnityEngine;
using System.Collections;
//List Collection을 사용하기 위해 Generic도 사용합니다.
using System.Collections.Generic;

public class MeshGen : MonoBehaviour {

    //ArrayList도 괜찮지만 편의상 List 객체로 선언해둡시다.
    //버텍스들의 위치를 저장할 객체입니다.
    public List<Vector3> _Vertex = new List<Vector3>();
    //다른 인접 버텍스의 Index값입니다.
    public List<int> _Tri = new List<int>();
    private Mesh mesh;

	// Use this for initialization
	void Start () {
        //시작하면 MeshFilter Compoent를 가져옵니다.
        mesh = GetComponent<MeshFilter>().mesh;

        //Position 값들인데, 편의상 풀었습니다.
        float x = transform.position.x;
        float y = transform.position.y;
        float z = transform.position.z;


        _Vertex.Add(new Vector3(x, y, z));
        _Vertex.Add(new Vector3(x + 1, y, z));
        _Vertex.Add(new Vector3(x + 1, y - 1, z));
        _Vertex.Add(new Vector3(x, y - 1, z));

         //이제부터는 버텍스 인덱스입니다.
         //이건 예제 코드 뒤에 설명하겠습니다.
         //1번 폴리곤
        _Tri.Add(0);
        _Tri.Add(1);
        _Tri.Add(3);
         //2번 폴리곤
        _Tri.Add(1);
        _Tri.Add(2);
        _Tri.Add(3);

        //메쉬를 청소해줍니다.
        mesh.Clear();
        //버텍스 데이터를 배열로 밀어 넣습니다.
        mesh.vertices = _Vertex.ToArray();
        //인접한 버텍스 데이터를 배열로 밀어 넣습니다.
        mesh.triangles = _Tri.ToArray();
        //메쉬를 생성합니다.
        mesh.Optimize();
        mesh.RecalculateNormals();
	}
}


실행해보면...
사용자 삽입 이미지
요롷콤 메쉬가 생성되어 있고,
Mesh 게임오브젝트 역시, 다음과 같이 값이 잘 들어가 있군요!
사용자 삽입 이미지
이제 인접 Index 값의 비밀을 알려드리죠.
비밀은 간단하게도 일종의 규칙입니다.
Polygon이 되려면 3개의 점이 있어야 합니다. 따라서, 그걸 간단히 3개씩 잘라서 사용하는 거죠.
사용자 삽입 이미지
실제로 다음과 같이 소스를 수정해보면...


        _Tri.Add(0);
        _Tri.Add(1);
        _Tri.Add(3);
        _Tri.Add(1);
        _Tri.Add(2);
        //_Tri.Add(3);


이런 상큼한 에러를 볼 수 있습니다.
사용자 삽입 이미지
"삼각형은 반드시 3의 배수여야 한다."

추가 설명은 여기까지 하고 이제 저 뻘건 녀석에게 옷을 입힐 차례입니다.
먼저 사용할 Texture가 있어야 겠지요?

깔끔한 128X128 px 짜리 체커입니다.
사용자 삽입 이미지



일반적으로 많이 사용하는 텍스쳐 Import후, Drag&Drop으로 게임오브젝트에 밀어 넣습니다.

사용자 삽입 이미지

플레이해보면... 어라?

사용자 삽입 이미지

예상과 다르게 시커먼 녀석만 올라왔네요.
이는 mesh데이터에 UV값을 넣지 않아서 생기는 현상입니다.
이제 UV값을 받을 수 있도록 소스를 추가해봅시다.


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

public class MeshGen : MonoBehaviour {

    public List<Vector3> _Vertex = new List<Vector3>();
    public List<int> _Tri = new List<int>();
    public List<Vector2> _UV = new List<Vector2>();
    private Mesh mesh;

    //Cell간의 Gap입니다. 5by5짜리 텍스쳐니까 간단히 1/5 = 0.2!
    private float _cellGap = 0.2f;
    //cell들의 Index를 저장합니다.
    public List<Vector2> _cell = new List<Vector2>();

    void Start () {
        mesh = GetComponent<MeshFilter>().mesh;

        float x = transform.position.x;
        float y = transform.position.y;
        float z = transform.position.z;


        _Vertex.Add(new Vector3(x, y, z));
        _Vertex.Add(new Vector3(x + 1, y, z));
        _Vertex.Add(new Vector3(x + 1, y - 1, z));
        _Vertex.Add(new Vector3(x, y - 1, z));

        _Tri.Add(0);
        _Tri.Add(1);
        _Tri.Add(3);
        _Tri.Add(1);
        _Tri.Add(2);
        _Tri.Add(3);

         //셀은 2개만 사용할겁니다. 0,0에 있는 검은색과 0,1에 있는 흰색입니다.
        _cell.Add(new Vector2(0, 0));
        _cell.Add(new Vector2(0, 1));

         //텍스쳐의 좌표를 UV에 넣습니다.
         //만약 List 인덱스 0번이라면 (0,0), (0.2,0), (0, 0.2), (0.2, 0.2)의 값을 가지겠죠?
        _UV.Add(new Vector2(_cellGap * _cell[1].x, _cellGap * _cell[1].y + _cellGap));
        _UV.Add(new Vector2(_cellGap * _cell[1].x + _cellGap, _cellGap * _cell[1].y + _cellGap));
        _UV.Add(new Vector2(_cellGap * _cell[1].x + _cellGap, _cellGap * _cell[1].y));
        _UV.Add(new Vector2(_cellGap * _cell[1].x, _cellGap * _cell[1].y));

        mesh.Clear();
        mesh.vertices = _Vertex.ToArray();
        mesh.triangles = _Tri.ToArray();
        //UV값을 넣습니다.
        mesh.uv = _UV.ToArray(); 
        mesh.Optimize();
        mesh.RecalculateNormals();
        }
}


이제 끝!
실행결과 입니다.

사용자 삽입 이미지
2014/02/23 16:47 2014/02/23 16:47
게임으로 돈벌기 힘듭니다.

이시점에서 링고게임즈가 얻었던 몇몇 데이터 수치를 공개하고자 합니다.

월사용자 대비 결재율은 최고 잘나온 게임이 2.9%였습니다.
(알고봤더니 업계 평균이 2%대입니다.)
양키엉아들이나 외국은 이 수치가 5~6%나온다고 합니다.



가상상품이 1달러~100달러까지 포진한다면 아마도 평균적으로 2달러 수준이 나올 것 같습니다.
(추정치입니다.)

가령 월 1만명이 다운받아서 사용한다면 200명 * 2000원 = 40만원의 수익을 추정할 수 있습니다.
여기에 기본 라이프 사이클이 3~6개월 정도 계산하면 대충 얼마정도의 수익을 얻을 수 있는지 알 수 있습니다.

월 10만 이라면 1명의 개발자가 먹고 살 정도의 수준이 가능합니다.
(수수료 제외하고 300만원 정도의 수익을 예상할 수 있습니다.)

물론 저 수치도 운이 좋다는 전재입니다.

왜 이렇게 박살이 났는가?
피쳐폰 시절에는 게임당 3~5천원의 다운로드당 수익을 챙길 수 있었습니다.
10만 다운이 일어나면 3~5억원을 매출을 기대할 수 있었죠.

하지만, 시장이 변했습니다.
저 수치를 그대로 대입하면, 다운로드당 수익은 20원에 불과합니다.

그럼 어떻게 해야 하는가?

결재율이 높은 곳으로 가는게 그나마 났다고 생각합니다.
해외마켓 5%를 목표로 가면 다운로드당 단가를 50원 정도로 올릴 수 있습니다.

그 외에는 남들이 안보는 마켓들을 공략해야 합니다.
찾아보면 많은 앱마켓이 존재합니다.
SKT, KT, LGT, Facebook, Amazon, Naver 등입니다.

다시말해, 한가지 마켓을 공략하는건 매우 위험합니다.
1개의 게임을 만들고 멀티플랫폼으로 출시해야 합니다.

즉, 플랫폼화 하지 않으면 앞으로 작은 게임회사가 살아 남기 힘들것입니다.

꿈을 접지 마세요. =)
2013/12/07 23:28 2013/12/07 23:28
Drawcall 땜시 고생좀 하다가 삽질하면서 알아낸 결과물입니다.

1. Drawcall이란?

화면에 Material을 1개 그리면 1DrawCall이 됩니다.
예를 들어, Mesh1과 Material1을 그리면 Drawcall 1입니다.
Mesh1, Mesh2를 Material1로 그리면 Drawcall 1입니다만, Mesh1은 Material1, Mesh2는 Material2로하면 Drawcall이 2가됩니다.
이는 DirectX든 OpenGL이든 똑같습니다.

* 인터넷에서 퍼온 Drawcall관련 자료입니다.
Mesh는 재각각이지만, Material이 1개이기 때문에 Drawcall 숫자는 1로 찍힙니다.
사용자 삽입 이미지


2. Drawcall이 증가하는게 왜 문제인가?

성능과 직결되는 문제이기 때문입니다. 예를 들어 위의 설명했지만, Mesh 데이터보다 텍스쳐로 사용되는 데이터의 크기가 더 큽니다. 만약 압축이 되어 있다면 압축을 해제해야 하는 문제도 생기겠죠? 암튼, Material을 GPU로 전송하는 수가 작을 수록 더 훌륭한 속도가 보장됩니다.
* PC기준이지만 좋은 자료 : http://www.slideshare.net/egohim/unity ··· imzation

3. 어떻게 해야하나?
자주 호출하는 것보다 VBO같은곳에 모아서 한꺼번에 찍어대면 Drawcall하는 횟수가 줄어서 궁극적으로는 성능이 개선될 수 있습니다. 배치방법은 2가지 방식으로 유니티에서는 지원하더군요.
- Dynamic Batch (움직이거나, 회전하거나, 커지거나, 작아지는!)
  . 300 Tris이하의 오브젝트 (만약에 자식 오브젝트로 등록하더라도... 똑같이 적용됩니다. 무조건 300 Tris)
  . Material을 1개의 Atlas에 다 때려넣어 주세요.
    (추천하는 Plugin은 Atlas 3D : http://u3d.as/content/tracki-studio/at ··· ui%2F5a0 단, NGUI사용자여야 합니다.)
  . Skinned Mesh 또는 실시간 그림자를 받는 녀석은 안됩니다.
- Static Batch (꿈쩍하지 않는녀석)
  . 우측상단에 Staic 체크해두면 알아서 돕니다.



2013/11/08 00:33 2013/11/08 00:33
간만에 써보는 군요.
오늘은 마지막회로 텍스쳐 블랜딩입니다.
흔히 지형을 그리고 풀인지 맨땅인지 붓으로 그릴 때 사용하는 쉐이더 입니다. =)
사용자 삽입 이미지

이런거 데슈~
(인기가 지지리도 없었기 땜시... 그리고 공부의 한계를 느끼게 되어서... 등등등의 이유입니다.)
먼저 Open Source Bumpmap을 만들어 주는 툴을 구해봅시다.
저는 Crazy Bump보다는 njob이 사용하기 쉽고 괜찮더군요.
다운로드후 설치하세요!.
이제 구글에서 Ground Texture라는 검색어로 바닥면 2개를 찾아 다운로드 합니다.
사용자 삽입 이미지
사용자 삽입 이미지

마지막으로 Asset Store에서 "Simple Vertex Painter"를 찾아 다운로드/Import합니다.
이제 SSE를 열어서 다음과 같이 노다가 합니다. ㅜㅡ
사용자 삽입 이미지

Node가 복잡하긴 하지만, 곱하기에 곱하기, 곱하기 들어가서 그렇지 큰 어려움은 없을 것입니다.
간단히 말해서 _BendMark의 범위만큼 지워주거나 생성해주는 로직입니다. =)
Setting 부분은 다음과 같이... =)
사용자 삽입 이미지

저장하고 Export합니다.
귀찮으신 분들은 첨부로 그려진 Node파일을 받으세염 =)
* 저는 가끔 이렇게 친절하기도 합니다. =)
사용자 삽입 이미지

이제 유니티 4.2부터 들어간 Quad Plane을 하나 만듭니다. 폴리곤 2개짜리의 아주 작은 용량의 Plane입니다.
사용자 삽입 이미지

사용자 삽입 이미지

Texture를 Drag해서 집어 넣습니다.
사용자 삽입 이미지

쉐이더를 방금 Export한 Vertex Blend로 합니다.
사용자 삽입 이미지

Texture가 사라졌지만, 걱정마세요 =)
이제 njob을 실행해, 2개의 Texture로 Bump를 만들차례입니다.
일반 텍스쳐를 Height맵으로 만든뒤에...
사용자 삽입 이미지

Height맵을 Bump로 만들면 끄읏!
사용자 삽입 이미지

사용자 삽입 이미지

이렇게 만들고 Mask로 사용할 이미지도 한장 저장해두세요. (Height 맵입니다.)
사용자 삽입 이미지

텍스쳐를 각각의 항목에 맞게 넣어 주세요.
사용자 삽입 이미지

이제 Windows에서 Vertex Painer를 열어 다음과 같이 테스트해봅시다.
사용자 삽입 이미지

컬러를 White로 바꾸면, 다시 채울 수 있습니다.
사용자 삽입 이미지

유니티 쉐이더 왠만하면 사서하세요! =)
만든다는 부분보다는 개념을 알려 드리는 차원에서 진행했습니다. =)
쉐이더 파일 다운로드 :
2013/08/19 16:15 2013/08/19 16:15
링고게임즈에서 사용하고 있는 서버의 Linq to SQL CRUD 패턴 몇가지를 공개합니다.
(별거 없어욤 =))


1. Create
SomeTable sm = new SomeTable();
sm.Id = _userid;
db.SomeTable.InsertOnSubmit(sm);
db.SubmitChanges();


2.1. Read #1
SomeTable sm = db.SomeTable.Single(e => e.Id == _userid);


2.2. Read #2
var q = from tmp in db.GetTable<SomeTable >()
         where tmp.Id == _userid
         select tmp;


3.1. Update #1
SomeTable  sm = bd.SomeTable.Single(e => e.Id == _userid);
sm.ScoreLink = int.Parse(_score);
db.SubmitChanges();


3.2. Update #2
var g = db.SomeTable.Where(x => x.isRead == 0).ToList();
g.ForEach(t => t.isRead = 1);
db.SubmitChanges();


4. Delete
SomeTable  sm = bd.SomeTable.Single(e => e.Id == _userid);
db.SomeTable.DeleteOnSubmit(sm);



ASP.NET MVC4
2013/07/26 21:03 2013/07/26 21:03
unity3D용으로 만들어진 암복호화 알고리즘이다.
(출처: 까먹음... T_T)



using UnityEngine;
using System.Collections;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System;

//중략 Key는 32바이트 "12345678901234567890123456789012"


     public static string Encrypt(string toEncrypt, string key)
    {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
    public static string Decrypt(string toDecrypt, string key)
    {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
        byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
        RijndaelManaged rDel = new RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return UTF8Encoding.UTF8.GetString(resultArray);
    }


* 서버에서도 같이 설정해두면 따로 싱크걱정 사라짐 =)
2013/07/26 17:40 2013/07/26 17:40
TAG ,
안녕하세요? 글뻥입니다.
어제에 이어서 오늘은  AC2 도반이신 이문상님 붙잡고... 야외카페에서 어떻게 Jar파일을 통합할지 같이 스타디한(라고 쓰고 지도 받았다고 읽습니다. ㅋ) 결과를 공유 드립니다.
아울러 출처를 밝히지 않은 불펌은 절대 불허합니다.
펌하실때 반드시 unitystudy.net 또는 wolfpack.pe.kr 을 밝혀주세요.
(링고게임즈의 지적 자산을 지켜주시길 부탁드립니다.)
어제 이클립스에 포팅한 녀석을 그대로 재활용할 예정입니다. =)
먼저 왼쪽 Navigator에서 New > Android Application Project를 클릭합니다.
사용자 삽입 이미지

Create custom launcher icon만 언체크하고 Next
사용자 삽입 이미지

그냥 막 넘어갑니다.
사용자 삽입 이미지

Finish 클릭!
사용자 삽입 이미지

새로 만든 프로젝트의 src 폴더를 타고 들어가 Class를 새로 만듭니다.
사용자 삽입 이미지
저는 ExtJarTest로 설정했어요.
사용자 삽입 이미지

사용할지 안할지는 모르겠지만... 하두 디인 "AndroidManifest.xml"라는 넘을 안전빵으로 새로만든 클래스명으로 수정했습니다.
사용자 삽입 이미지

어제 만든 AndroidTest 프로젝트에서 class.jar 파일을 복사하여 새로 만든 프로젝트에 넣어주세요.
사용자 삽입 이미지
Ctrl+c, Ctrl+v해도 됩니다. =)
사용자 삽입 이미지
그리고 새로 만든 프로젝트의 Properties를 클릭!
사용자 삽입 이미지
Java Build Path에서 Libraries 탭에 Add Jars를 클릭
사용자 삽입 이미지


방금 복사한 Class.Jar파일을 선택해 줍니다.
사용자 삽입 이미지

그리고 새로 만든 ExtJarTest 소스를 어제와 같이 수정해줍니다.
extJarCall이라는 메소드를 만들었고 거기에 String 데이터를 넣으면 " Called!"라는 메시지를 붙여서 반환하는 구조입니다.
사용자 삽입 이미지

소스가 있는 폴더에 우클릭하시고 Export합니다.
사용자 삽입 이미지


Java에 Jar file선택!
사용자 삽입 이미지

다음과 같이 소스 폴더만 선택하고 나머지는 다 무시.
Export할 경로는 어제 Export해둔 (지난강좌 참조) 프로젝트의 Lib 폴더로...
사용자 삽입 이미지
다음과 같이 Export되면 성공입니다. =)
사용자 삽입 이미지
이제 어제 (지난강좌)의 프로젝트를 선택하고 속성을 눌러 줍니다.
사용자 삽입 이미지
Add Jars하시고 방금 들어온 ExtJar.jar 파일을 선택!
사용자 삽입 이미지
이렇게 들어오면 성공입니다.
사용자 삽입 이미지
어제 소스를 약간 수정해서 ExtJarTest.extJarCall() 메소드를 호출해줍니다.
사용자 삽입 이미지
이제 이클립스에서 빌드하면~~~~
유니티에서 자바로 보낸 문자에 Called!라는 문자열이 잘붙어서 따라옵니다. =)
사용자 삽입 이미지


오늘도 고생많으셨습니다.
이 땅의 모든 개발자분들 기운내세여 =)
마지막으로 바쁘신내주셔서 친절히 답변해 주신 이득우님께도 감사드립니다. =)
2013/05/06 22:58 2013/05/06 22:58
안녕하세요? 글뻥입니다.
한 이틀 정도 이클립스 공부하고 강좌 올립니다. =)
틀려도 뭐라 하지마세염 ㅡㅡ;;
안드로이드 연동 이슈땜시 돌아 버릴려해서, 아무 생각없이 여기 저기 자료 찾아서 연동해봤습니다.
유니티가 자바를 연동하는 방식은 2가지가 있어요.
1. 유니티를 Eclipse로 Export 해서 일부 Class.jar 파일을 뽑은 후에 원하는 대로 Class를 만들어서 다시 Plugin현태로 붙이는 방법
2. 유니티를 Eclipse로 Export한 후에 그 안에서 삽질하는 방법
첫번째는 주로 유료플러그인에서 많이 쓰는 방식이고, 플러그인 만들거 아니니까 포기하고 바로 2번째로 가봅시다.
(사실은 첫번째로 OO 붙이다가 울 이사님 좌절... 옆에서 겜 만드는 저도 좌절... 그래서 겜 만드는 거 급 포기하고 OO붙이는 작업 긴급 붙음... 뭐 이런 시나리오 되겠슴돠..)
암튼 각설하고 유니티를 열고 새로 프로젝트를 만들어요.
그리고 아무 생각하지 말고 게임오브젝트로 GUI TEXT를 넣습니다.
사용자 삽입 이미지

이름을 "TEST"로 변경합니다.
사용자 삽입 이미지

이제 자바파일을 호출할 녀석을 만듭니다.
저는 TestMethod라는 이름으로 스크립트를 하나 만들었습니다.
using UnityEngine;
using System.Collections;

public class TestMethod : MonoBehaviour {

//    public AndroidJavaObject activity;


// 시작하면 자바에 있는 메소드를 호출합니다. 기억합시다. "initActivity"!!!!!
void Start () {
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                jo.Call("initActivity", "unity to android"); //여기가 젤 중요함!
            }
        }
}

//여기는 자바가 호출하는 메소드입니다.
    public void AndroidLog (string a)
    {
        transform.GetComponent<GUIText>().text = a;
}
}
위에 Start땜시 멘붕이 왔죠.
"ㅅㅂ 당췌 이걸 어떻게 찾는고야!!?!!"
하지만, 유니티는 똑똑합니다... UnityPlayerActivity를 상속받은 넘들은 무조건 그냥 이게 먹힙니다.
물론, Manifest에서 설정해줘야 하지만... 설정법은 좀있다 다시 거론하면서 일단 여기까지 하고 넘어갑시다.
그리고 아까 만들어둔 TEST에 Attach합니다.
Player Setting에서는 다음과 같이 설정했습니다.
사용자 삽입 이미지

그리고 인증키도 생성해줬습니다. Create New Keystore를 클릭하시면 됩니다.
사용자 삽입 이미지

이제 Eclipse로 Export!
사용자 삽입 이미지

이제 유니티는 잠시 닫아주셔도 좋습니다. =)
안드로이드 SDK가 깔려있는 폴더를 보면... eclipse가 보이실거예요!
사용자 삽입 이미지
이제 eclipse를 살포시 따블클릭!
1. 파일에 Import를 클릭합니다.
사용자 삽입 이미지

Exit 어쩌구 항목을 클릭하구요...
사용자 삽입 이미지

폴더를 선택하면 끝!
사용자 삽입 이미지

좌측 네비게이션바에 주목해주세요!
사용자 삽입 이미지

src라는 폴더를 계속 열어서 타고 들어가면...
사용자 삽입 이미지

파일이 3개보입니다.
ProcyActivity는 버전을 확인해서 버전이 낮은넘은 그냥 Activity로, 높은 넘은 NativeActivity로 보낸다고 합니다.
뭐... 이런게 있구나 정도로 가볍게 쌩까주시고...
파일을 하나 만듭니다.
사용자 삽입 이미지

저는 "TestJava.java"로 생성했지요....
이제 다음의 소스를 부앜~ 긁어다 붙입니다.
package com.lingo.androidtest;
import com.unity3d.player.*;
import android.os.Bundle;
public class TestJava extends UnityPlayerActivity {
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
   
    public void initActivity(final String messageFromUnity)
    {
        runOnUiThread(new Runnable() {
            public void run()
            {
            UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
               }
          });
    }
}
한가지 주의하실점은 UI Thread 테스트를 위해 만든 녀석이
    public void initActivity(final String messageFromUnity)
    {
        runOnUiThread(new Runnable() {
            public void run()
            {
            UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
               }
          });
    }
요 부분입니다. 이걸... Thread가 불필요하다면
    public void initActivity(String messageFromUnity)
    {
    UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);
    }
요롷게 고쳐주세요.
암튼 이제 마지막 순서입니다. Manifest라는 아주 지독한 넘을 고쳐야 하죠!
<activity> 테그가 3개 보일텐데 2개는 날려버리시고...
요렇게 생긴넘이 포함된 Activity 테그만 남겨두신뒤에
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
사용자 삽입 이미지
위와 같이 이름만 ".TestJava"로 변경합니다.
이제 실행!
사용자 삽입 이미지


제가 삽질했던 경험에 따라 몇가지 얻은 정보를 이자리에서 공유해야 겠어요.
먼저, 유니티->자바인 경우
가장 먼저 해야 할건...
UnityPlayerActivity 를 확장한 클래스를 main으로 등록해주는 겁니다.
이건 Manifest에서 진행하는 거죠.
다시말해... Manifest에...
<activity android:name=".TestJava" 어쩌구 저쩌구... >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>
의 구조로 사용자가 생성한 Class가 물리지 않으면 Fail!
2번째로 사용자가 확장한 클래스는 반드시...
"public class TestJava extends UnityPlayerActivity" 의 구조여야 한다는 점입니다.
이 정도 상황까지 되면 아래와 같은 코드로 호출이 가능합니다.
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                jo.Call("initActivity", "unity to android"); //여기가 젤 중요함!
            }
        }
물론 위의 코드는 다음과 같이 재정의 될 수 있습니다.
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")
 jo.Call("initActivity", "unity to android");
별도로 오브젝트와 클래스를 찾지않아도 되는 아주 훌륭한 상황되겠습니다.
반대로 자바가 유니티를 호출할때는 다음의 순서로 갑니다.
오브젝트, 메소드명, Argument
따라서, 다음과 같은 코드가 작동할 수 있는 것이죠.
Scene에만 떠 있다면 암생각 없이 작동됩니다.
    UnityPlayer.UnitySendMessage("TEST", "AndroidLog", messageFromUnity);


몇 번이나 밥상 엎어 버릴 생각이었는데... 이틀 정도의 삽질로 해결이 되서 다행이네욤.
물론, 플러그인들끼리 Merge하는건 또 다른 문제같습니다.
그롬~ 수고하세욤~
2013/05/06 22:53 2013/05/06 22:53

강좌 들어가지 전에... 포프님 찬양! =)
오늘의 강좌는 포프님의 연산, 상수 강좌를 따라했습니다. (출처 : http://www.gamedevforever.com/71)


프로그래머들이시니 별 어려움 없이 이해하실거라 생각하고 그냥 따라해보세요!

New Graph로 깨끗하게 해준뒤에 "마우스 우클릭하시고" Operation 탭을 보시면 4칙연산자를 발견할 수 있습니다.

사용자 삽입 이미지
minors 찾느라 뺑이 쳤지만... 용서하겠습니다. Subtract라는 알흠다운 단어가 있기때문에.. 흠흠..

unity3D에서 수없이 타이핑했을 Vector3, 그 밑에 자세히 보면 보이는 Vector4가 오늘의 주제입니다.
정확하게는 RGBA를 정의한 Color code입죠.

일단 4가지 연산자를 다 꺼내 놓습니다. (테스트할때는 무조건 무식하게..)
사용자 삽입 이미지
그리고 Constant 탭에서 float4 const 를 클릭합니다.
사용자 삽입 이미지


오른쪽에 Node탭을 클릭하면 값을 입력할 수 있죠.
사용자 삽입 이미지


이렇게 2개를 만들어서 테스트 합니다.
먼저 "X"
사용자 삽입 이미지
그리고 "+"
사용자 삽입 이미지
그리고 또, "/"
사용자 삽입 이미지


마지막으로 "-"
사용자 삽입 이미지


별거 없습니다.
Vector4(0.5f, 0.5f, 0.5f, 0.5f) 값에 Vector4(0.5f, 0.5f, 0.5f, 0.5f)를 곱하면  (0.25, 0.25, 0.25, 0.25) 가 나오니까 당연히 어둡고,

Vector4(0.5f, 0.5f, 0.5f, 0.5f) 값에 Vector4(0.5f, 0.5f, 0.5f, 0.5f)를 더하면  (1.0, 1.0, 1.0, 1.0)이 나오니까 당연히 밝고,
Vector4(0.5f, 0.5f, 0.5f, 0.5f) 값에 Vector4(0.5f, 0.5f, 0.5f, 0.5f)를 나누면  (1.0, 1.0, 1.0, 1.0)이 나오니까 당연히 밝고,

Vector4(0.5f, 0.5f, 0.5f, 0.5f) 값에 Vector4(0.5f, 0.5f, 0.5f, 0.5f)를 빼면  (0, 0, 0, 0)이 나오니까 당연히 안나옵니다.



이제부터 잉여짓 들어갑니다.


상수를 하나만 다음과 같이 추가해봅니다.
사용자 삽입 이미지
추가하는 방법은 Constant 탭에서 float 을 선택하면 됩니다.

사용자 삽입 이미지
아마도 결과는 같겠죠?



이제 지난강좌와 같이 Smapled2D를 넣어 봅시다.
사용자 삽입 이미지


Alpha 설정은 2강에서 이미 했습니다. =)

그리고, 이건 숙제입니다. =) 직접해보시기 바랍니다.

(출처 : http://www.gamedevforever.com/73)

Texture는 아래에 있는걸 사용하세욤.
사용자 삽입 이미지


사용자 삽입 이미지


한가지 주의할 점은 unity에서 Normalmap으로 인식할 수 있도록 다음과 같이 설정 해줘야 합니다.

사용자 삽입 이미지



제가한 버전은... 여기있습니다.
주의 1. 원래 강좌에서 Ambient Color는 유니티에서 무의미합니다. 반사광은 Lightmap이나 LightProbe로... ㅡㅡ;
주의 2. Emission 맵은 제가 만들지 모르므로 패스 ㅡㅡ;;

사용자 삽입 이미지





2013/04/01 00:55 2013/04/01 00:55
원래 강좌는 "Shader FX"강좌입니다.
(출처 : http://www.gamedevforever.com/15)


저는 쉐이더 쪽은 왕 문외한이기 땜시 위의 예제를 따라서 한 강좌씩 따라가보려합니다. =)

Unity3D에서는 Free로 풀린 Strumpy Shader Editor가 있습니다.

Windows에서 Asset Store로 가셔서 Import!
사용자 삽입 이미지


메뉴에서 Shader Editor를 클릭하여 보면...
사용자 삽입 이미지


복잡한 선들이 가득합니다.
사용자 삽입 이미지


우리가 따라할 강좌의 초반부는 "뻘갱이" 만들기 입니다. (출처 : http://www.gamedevforever.com/32)
에디터 하단에 있는 File > New Graph를 클릭! 하여 깨끗이 정리합니다.
사용자 삽입 이미지
다 됐다면 빈곳에 마우스 우클릭하면 영어들이... ㅡㅡ;;
여기서 속성을 뜻하는 Properties를 클릭하고 Color를 클릭!
사용자 삽입 이미지

그럼 벌써부터 시뻘건 넘이 뜨면서 Not Configured라고 뜹니다.
사용자 삽입 이미지

그러나, 걱정마십시오! 오른쪽에 이름만 넣어 주면 되니까요... ㅡㅡ;;
Node 탭에서 "SimpleRed"라고 입력하고 Add를 눌러주면...
사용자 삽입 이미지
짜잔!
사용자 삽입 이미지
아무일 없다는 듯이 바뀝니다.
이제 우리가 할 일은 Node를 이어 주는 겁니다.

Master의 Diffuse 오른쪽에 있는 작은 사각형을 클릭하고 Color의 RGBA라고 되어 있는 왼쪽의 작은 사각형으로 연결합니다.
사용자 삽입 이미지
사용자 삽입 이미지
아직도 오른쪽 탭의 "Setting"에는 붉은 글씨가 있을 텐데... "Setting을 클릭하고 Shader Name을 입력하면 끝!
(저는 Test로 입력했습니다.)
사용자 삽입 이미지
에디터 하단의 Preview를 클릭해서 Preview의 공이 어떻게 바뀌나 봅시다.
사용자 삽입 이미지
이제 Inputs에서 Color를 아래와 같이 변경하면...
사용자 삽입 이미지
짜잔!
사용자 삽입 이미지
실제 모델에 적용하기 위해서, File에 Export 어쩌구를 클릭하면 .shader 파일로 출력할 수 있습니다.
사용자 삽입 이미지
test.shader로 저장!
사용자 삽입 이미지


Project 탭에서 Material을 하나 생성하고 방금만든 Test쉐이더를 설정합니다.
사용자 삽입 이미지
사용자 삽입 이미지
이제 큐브에 적용해보면...
사용자 삽입 이미지
알흠다운 뻘갱이 큐브가 보이는 군염!

다음 강좌 역시 원작자이신 "포프"님의 예제로 진행해보겠슴돠 =)

포프님 만쉐!
2013/03/29 21:19 2013/03/29 21:19