꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by zinzza


Apparelbase.MVVMBase.dll


안녕하세요 zinzza, 연두父, 이경배입니다.

2회입니다. 이번엔 지난번에 이어 MVVM의 장점을 이해하기 위해 또 한번 삽질의 시간을 갖고자 합니다.

하지만 이번걸 이해해야 다음 진행이 가능할거 같습니다.


C&P 한거지만... 다시한번 대상설명을 드리자면^^;;;


이 글의 대상은 엄청 간단한 C#책을 살짝쿵 읽어본 기획자, 대학, 학원등에서 C#프로그램을 좀 배운 수준의 사람들을 대상으로 적었습니다.


일단... 프로그래머 분들께서는 이 글의 오류를 찾아 저에게 제출해주시고, 그럴 목적이 아니시라면 읽지 말고 나가주세요.(부끄로아요ㅜㅜ)


아... MVVM의 장점 하나 설명하려고 별별 삽질을 다 해봅니다.
그럼 지난번에 만든걸 MVVM패턴으로 만들어보겠습니다.




먼저 새 프로젝트를 만들어봅시다.
뭐... 다 아는걸 괜히...^^;




그 다음엔 제가 첨부해 놓은 Apparelbase.MVVMBase.dll을 참조에 추가합니다.


Apparelbase.MVVMBase.dll


* 방법은 솔루션 탐색기의 참조에서 오른쪽버튼-> 참조추가-> 찾아보기 에서 찾아 추가해주시면 됩니다.

MVVM패턴을 하기 위해서는 몇가지 특정 자료형을 사용해야 하는데 그 사용을 좀 편리하게 해주는 겁니다.  저희 회사에서 사용하는 것들 중 필요한것만 살짝 뺐습니다. 그래도 괜히 우리 팀 이름을 붙여 봤습니다^^;


그리고 MainWindow를 꾸며봅시다!




역시 껍대기는 간단하게 만들 수 있으니 스킵합니다.

자~ 그 다음엔 ViewModel을 추가 해야 합니다.
뷰는? MainWindow.xaml 이 뷰 입니다^^;
모델은? 이건 좀 나중에^^;

솔루션 탐색기의 프로젝트 이름에서 오른쪽버튼 -> 추가-> 클래스 

클래스 이름은 알아보기 쉽게 MainViewModel.cs 로 가죠. 

 MainViewModel.cs를 열어서 위의 빨간부분을 입력합니다.


using Apparelbase.MVVMBase; 는 아까 추가한 dll을 이 파일에서 사용하겠다는 뜻입니다.
public은... 여기저기서 쓸려고 걍 넣은겁니다. 일단 보안은 신경 안쓰니까 편하게^^;
:ObservableObject 는 뷰모델의 기본이 되는 프로퍼티들이 정의되어있습니다.(이게 dll안에 들어있던놈입니다.) 당장 몰라도 되니 그냥 넘어가죠^^;

자~ 이제 뷰모델을 만들었으니 이 안에 데이터를 제어하는 코드들을 넣어야 합니다.
아까 만든 Winform 보다 조금 복잡한 코드입니다.
음... 우선 TestNumber 변수를 하나 선언할까요?



헉!  이게 뭔가요?


이건 변수가 아니고 프로퍼티라고 하는겁니다.  더 자세히 말씀드리면 의존프로퍼티(Defendency Property) 라고 하는거죠. 복잡한가요? 차근차근 보면 뭐^^;;




다시 한번 MVVM에 대한 그림을 보시면 Properties라는 부분이 있을껍니다.
바로 그 Property중에 하나를 선언한겁니다^^;

MVVM에서는 Property가 변하면 View에 자동으로 반영됩니다. 이거 꽤 편해요!
이번화에서는 Properties와 ICommands 를 사용할껍니다.

아! 프로퍼티에 대해서 알고 계시면 3-2의 빨간 글씨만 보시고 넘어가셔도 무방합니다.

1. 먼저 노란 #region은 신경 안쓰셔도 됩니다. 그냥 여기서부터 여기까지 TestNumber에 대한 내용이다~ 라는거고 프로그램에는 아무 역할도 안하는놈입니다.
2. 소문자로 시작하는(습관입니다)testNumber 변수는 실제 값을 저장하는 변수입니다.
3. public 으로 선언되고 대문자로 시작하는 TestNumber 가 바로 의존프로퍼티인데요
사실 이 MainViewModel을 외부에서 접근할때는 testNumber로 접근하는게 아니고 TestNumber를 통해 값을 설정하고 조회합니다.
TestNumber에는 testNumber를 설정, 조회하는 방법을 정의하는거죠.
그래서! get과 set 을 갖고 있습니다.
3-1 get은 간단하니 먼저 설명합니다.
그냥 return this.testNumber; testNumber의 값을 바로 읽는겁니다.(왜 이런 삽질을...ㅎㅎ 천천히 아셔도 됩니다. )
3-2 set 역시 this.testNumber = value; 로 TestNumber에 설정되는 값을 바로 testNumber에 지정합니다.
하지만 코드가 2줄 더 있는데요, if를 통해 같은 값인 경우 다시 지정하지 않게 하는 코드 한줄,
그리고 this.RaisePropertyChanged(“TestNumber”); 를 잘 기억해 두시기 바랍니다.
“나 변했어요~~~” 하고 프로그램한테 알려주는 메소드입니다.

음... 위 내용이 복잡하시면
변수를 선언할때 위 형태를 유지해 주시고 testNumber, TestNumber, int  이 3가지만 필요에 맞게 변형해서 사용하시면 됩니다.(저도 처음엔 그렇게 했어요)

자 이제 이걸 컨트롤 하는 ICommands를 만들어봅시다.
아! ICommand를 추가하기 전에 MainViewModel 위쪽에 using System.Windows.Input;  을 추가 해 줘야 합니다. ICommand가 여기 있거든요.
이제 추가해줍시다!


으악!!


복잡하지만 정 귀찮으시면 이번 역시 plus와 Plus 만 이름에 맞춰 바꿔쓰시면 됩니다.

물론 설명도 해야겠죠 ㅜㅜ
1. 먼저 소문자로 시작하는(역시나 습관) plusCommand 를 하나 선언하고요,
2. 대문자로 시작하는 PlusCommand를 하나 선언합니다.
get 구현하되 형식을 유지하고 그냥 plus와 Plus 부분만 수정한다고 기억하세요. 자세한 설명은 생략합니다.(너무 길어져요 ㅜㅜ)
3. CanPlus() 는 이 ICommand가 실행 가능한 상황인지 아닌지를 판단하는 메소드 입니다. 뒤에 다시 설명할꺼고요, 지금은 무조건 true를 반환하게 되어있습니다.
4. Plus() 메소드에 진짜 필요한 코드가 들어가는겁니다. 아... 이 간단한거 한줄 넣으려고 이게 뭔 짓입니까 ㅜㅜ?

마찬가지로 마이너스 커맨드도 만들어야겠죠?




뭐... plus, Plus 를 minus, Minus로 바꾼거 와 ++가 --로 바뀐거 말고는 달라진게 없군요.
암튼 이제 ViewModel을 다 만들었습니다! 실행!!!!!!!!!!! F5!!!!!!!!!!!!!!!





















.

.

.




.

.

.

.

.

.

.




































.

.

.

.

.

.

.

.

.

.

.

.

.

.














허허... 안되네....



왜 안될까요? 그건 View랑 ViewModel을 연결해주지 않았기 때문입니다.


솔루션 탐색기에서 MainWindow.xaml.cs를 선택해 줍니다.




그리고 연결하는 코드를 넣어주죠.



한줄만 넣어주시면 됩니다.  이 뷰의 뷰모델은 MainViewModel이다~ 라는 뜻이죠.

다시 MainWindow.xaml 파일을 열어서 마치 html코드 처럼 생긴 xaml코드를 봅니다.



저는 보기 편하게 하려고 Enter를 좀 쳐놔서 모양이 다를껍니다.
아마 한줄에 죽~ 나오실꺼에요.
순서대로 갑니다~
1. 먼저 Label의 Content를 “{Binding TestNumber}” 라고 수정해줍니다. - ViewModel의 TestNumber 프로퍼티를 연결한겁니다.
2. + Button에 Command="{Binding PlusCommand}" 를 추가 해 줍니다. - ViewModel의 PlusCommand ICommand를 연결한겁니다.
3. - Button에 Command="{Binding MinusCommand}" 를 추가 해 줍니다. - ViewModel의 MinusCommand ICommand를 연결한겁니다.




이렇게요^^;

아~~~~ 정말 수고하셨습니다~~~~ 이제 진짜로 F5!
실행을 확인합니다.
정말... Winform에서 간단하던 걸 왜 이 고생을 한 건지 이해가 안됩니다.


아~이해안되~~

자... 이제 거의 다 왔습니다.

앞에Winform에서 했던 3번의 수정을 더 하면 끝인거죠-_-??????????



또....-_-?



ㅎㅎㅎ 그레도 MVVM은 수정이 좀 쉬우니까요- 그래서 쓰는 거라니깐요^^;
자... 처음이 뭐였죠?
Label을 TextBox 로 변경?

해보죠 뭐.



MainWindow.xaml 파일에서 Label 을 TextBox로 수정하고 Content를 Text로 수정해주세요.(TextBox에는 Content라는 속성이 없고, Text라는 프로퍼티가 있거든요)
끗!

그 다음은 뭐였죠?
아... 0미만으로 내려가지 않기, 10초과해서 올라가지 않기였죠?
그럼 이번엔 MainViewModel의 TestNumber 프로퍼티를 보시죠.  
값을 지정하는거니까 set 부분을 수정해줘야 합니다.
if (this.testNumber != value) 부분을
if (this.testNumber != value && value >= 0 && value <= 10) 으로 수정해주세요.



0보다 작거나 10보다 큰 값은 아예 testNumber에 지정되지 않게 됩니다.
끗!

자~ 그 다음!
아! 버튼 비활성화였죠?
0일때10일때...
이번엔 PlusCommand와 MinusCommand에서 CanPlus, CanMinus 메소드를 수정해야 할 시점입니다.
CanPlus메소드에서
if (true) 를 if (this.TestNumber<10) 으로 고쳐주세요.



CanMinus메소드에서
if (true) 를 if (this.TestNumber>0) 으로 고쳐주세요.




각 커맨드가 조건에 의해서 실행되고 안되고를 지정해주는건데요, 이렇게만 해주면 버튼이 조건에 의해 자동으로 활성화, 비활성화됩니다.(오옷!)

끗!

자~~~~~ 마지막! 이름 변경!
각 컨트롤들의 Name 속성을 바꿔주세요.
코드는 바꾸실 필요 없습니다^^;(이름으로 연결된게 아니라 값 자체가 연결(Binding 된거)니까요)
끗!

아... 만들때는 좀 힘들었지만(사실 설명이 힘들고 익숙하지 않은거죠, 이텔릭체로 써놓은 것처럼 그냥 규칙대로 쓰고,  크게 어렵지도 않아요. 타이핑이 많을 뿐.)





아무튼..저는 힘들었어요.

이렇게 MVVM 패턴은 유지보수, UI수정등을 쉽게 할 수 있다는 장점을 갖고 있느 패턴입니다.
자... 아무튼 일단 MVVM과 WPF와 C#과 XML을 이용해서 우리 놀개영의 공식 동내북 달땡님이 원하는 툴을 함 만들어 보겠습니다!
고고고!



반응형
,
Posted by zinzza

안녕하세요 zinzza, 연두父, 이경배입니다.

오랫만에 글을 적어봅니다.

글을 적는 시점에서 제 계획은 C#으로 게임에 응용될 간단한 툴을 제작해보려고 합니다.


이 글의 대상은 엄청 간단한 C#책을 살짝쿵 읽어본 기획자, 대학, 학원등에서 C#프로그램을 좀 배운 수준의 사람들을 대상으로 적었습니다.


일단... 프로그래머 분들께서는 이 글의 오류를 찾아 저에게 제출해주시고, 그럴 목적이 아니시라면 읽지 말고 나가주세요.(부끄로아요ㅜㅜ)


그 시작은...



시작.


그리고 강의에서 만들려고 하는 툴은 이러하지요.


학습목표.


목표는 이러합니다.


이걸... WPF와 XML과 C#을 이용해서 만들려고 합니다. MVVM패턴으로요^^;
천~천~히(달땡님 미추어버리게)

MVVM이란?
뭐든지 정의를 찾아야 할때는 만든놈들한테 물어봐야 합니다.
http://msdn.microsoft.com/ko-kr/magazine/dd419663.aspx#id0090006
Microsoft에 나와있는 MVVM에 대한 정의.


주의!
위 내용을 읽으려고 시도하던 중 뭔 소린지 모르겠다 할때는 일단 읽는 것을 중단하고 아래로 진행해야 합니다.  저걸 이해하겠다고 사전찾고 MVC, MVP 등... 모르는 것들의 정의를 찾아 여행여행 하다보면... 똑똑해집니다-o-;
하지만 저는 위의 내용들을 이해하려고 하다가 포기하게 되더군요. 





그레서 전 포기하는것보다 “모르고 마구자비로 하다보니 알게되었다” 의 테크를 추천합니다. 사실... 저도 잘 모르는게 많고요 ㅜㅜ

내가 생각하는 MVVM
그레도 아예 모르고 넘어가는 것 보다는 조금이라도 알 수 있게... 제가 이해하고 있는걸 풀어보겠습니다. 이것까지 모르겠으면 또 넘어가 봅시다.

MVVM은 프로그램을 개발할때 Model 과 View와 ViewModel을 나눠서 개발하자는 뜻입니다.
그림으로 볼까요?


출처:
http://openlightgroup.net/Blog/tabid/58/EntryId/84/Silverlight-MVVM-The-Revolution-Has-Begun.aspx

오~~ 설명이 잘 되어있는 이미지군요.
(이미지 안에 있는 UI, Collections,...Web Services등은 무시하세요. 나중에 나중에^^)

해석이 다를 수 있지만 제가 생각하는 단어로 매칭을 좀 해보면
Model은 데이타, 자료 등으로 해석할 수 있을거 같습니다.
View는 UI정도로 해석해볼까요?
ViewModel은... 글쎄요-_-??? 그냥 뷰모델이죠 뭐.(데이타를 제어하는 로직, 화면에서 내려지는 명령 처리등이 들어갑니다)



저도 잘 모른다니깐요ㅜㅜ


반복하는 거지만 MVVM은 위 그림처럼 프로그램에서 UI와 데이터, 로직을 분리하겠다는 뜻입니다.

그나저나 왜 나누냐구요-_-?
이유는 이런 상황에 대처하기 위해서 입니다.
일반적인? Winform에서는 뷰를 제어하는 코드가 직접 들어가죠.
예를들어 텍스트박스에 글자를 넣기 위해서는...
form1.txtName = “연두부”;
이런 코드 말이죠.
만약에 위 코드에서 텍스트박스를 label로 바꾼다면요? 그 label을 또 다시 TextBox으로 바꾼다면?
뷰는 당연히 바꾸는거고,  모든 소스코드를 뒤져가며 txtName을 lblName으로 또 txtblockName등으로 바꿔줘야 합니다.(뒤에 간단한 실습으로 한번 보여드리겠습니다.)
물론 Ctrl + H는 저도 잘 알고있습니다만... 어느정도 규모가 되는 프로그램이라면 그것도 보통 일은 아니죠-_-;
이런 문제를 해결하는 방법으로 MVC라는 패턴이 생겨났고, MVC의 파생된 형태라고 생각하면 됩니다.
그럼 어떻게 나누냐구요-_-?
그건 좀 있다가^^;

뭐 그림으로도 설명은 잘 안되는군요-_-;
일단 막 진행해 볼까요?
하다보면 되겠죠 뭐~ 안되서 질문이 올라오면 업데이트도 좀 하고... ㅎ

왜 MVVM인가?
여러가지 장점이 있지만 가장 큰 이유는...
개발자가 WPF와 MVVM에 익숙해진 뒤에는 이 둘을 차별화하기가 어려워집니다.(msdn)
때문입니다.
제가 회사에서 거의 대부분의 프로젝트를 MVVM패턴을 이용하거든요.
실제로 MVVM에 익숙해진 다음 WinForm프로그래밍을 하면 짜증이 밀려오는 재미있는 경험을 하게됩니다.





그럼 직접 그 짜증을 경험해봅시다.
C#으로 간단하게 화면에 숫자를 표시하고 “+”버튼을 누를때마다 숫자가 증가하고, “-”버튼을 누를때마다 숫자가 감소하는 프로그램을 만들어봅시다.

일반적인 윈폼으로 말이죠^^;



먼저 폼을 디자인합니다. label 하나와 button 2개로 구성합니다.
이부분은 자세히 설명하지 않겠습니다.
그리고, 버튼의 크기다 다르고 디자인이 구린건 님들 모니터가 불량인겁니다.
자 그럼 + 버튼과 -버튼을 더블클릭해서 소스를 입력합시다.




1. 숫자변수 TestNumber를 선언했습니다.
2. + 버튼의 코드입니다.
3. -버튼의 코드입니다.

자... 이젠 문제점을 파악해야 하니 이 프로그램의 label을 textbox로 변경해보겠습니다.



자... 이렇게 label을 지우고 textbox를 올려놨습니다.




오호라... 역시나 에러가뜨는군요.
위의 label1을 textbox1이라고 바꿔주면 일단 정상적으로 돌아갑니다^^;

이왕 하는거 좀 더 가보죠.
최대값은 10, 최소값은 0으로 지정해서 0이 되면 -버튼을 눌러도 숫자가 변하지 않게 해보는겁니다.
+버튼도 마찬가지로 10 이상 증가하지 않게^^;




오~~~ 점점 코드가 늘어가는군요. 복잡해요.

하나만 더 해봅시다.
이번엔 0일때 -버튼이 비활성화, 10일때 +버튼이 비활성화 되는겁니다.

사실 0일때 -버튼을 누를 일이 없으니까요.^^;




자 저는 CheckButtonEnable() 이라는 함수를 하나 만들어서 두 버튼 이벤트에 추가해줬습니다.

ㅎㅎㅎ 이제 One more thing!
프로그램을 요모냥으로 짰더니 누군가 와서 이렇게 말합니다.
“야 인간아~ button1이 뭐냐? 당장 txtNumber, btnPlus, btnMinus로 바꿔!” 라고 말이죠.




정신차리고 뭘 해야 할지... 생각 좀 해봅시다. 뭘 해야하지-_-?

1. 일단 뷰에 가서 컨트롤들의 이름을 변경합니다.
2. 이벤트 이름이 바뀝니다. 그럼 각 버튼 이벤트에 있는 코드를 복사해서 새로 생긴 btnPlus_Click , btnMinus_Click 이벤트쪽으로복사합니다.
3. 코드에서 textbox1 로 되어있는 코드들을 전부 txtNumber로 변경합니다.
4. 코드에서 button1로 되어있는 코드들을 전부 btnPlus로 변경합니다.
5. 코드에서 button2로 되어있는 코드들을 전부 btnMinus로 변경합니다.


안해-o-!



이 연두 코딱지만한 프로그램에서 할일이 이따위로 많은데 실제로 회사에서 하는 프로젝트면... 에효...


그리하야!

이런 문제를 해결하고자 MVVM을 사용합니다!!! 

다음번엔 똑같은 짓을 MVVM패턴으로 해봅니다. ㅎㅎㅎㅎ


그럼 다음시간까지~ 안녕~~~



반응형
,
Posted by 김포프

예제코드 다운받기


  • C#과 XNA를 이용해서 만들었습니다.

  • XNA를 설치하셔야 합니다.


게임보다는 에디터 따위의 툴에서 더 유용한 기법입니다. 예전에 개인 프로젝트에서 장난삼아 만들어 봤던 놈인데 그뒤로도 몇번이나 동일한 기법을 여러 툴에서 구현하다보니 올리면 유용하겠다 싶어서..... 이미 알고계시는 분들도 많겠지만 혹시나 모르시는 분들을 위해 여기 올리면 좋겠다고 생각해서 올립니다.


이 기법이 해결하려고 하는 건 간단합니다. 맵 에디터 같은 프로그램에서 화면에 있는 물체를 마우스로 클릭해서 선택하는걸 졸라~ 빠르게 구현하는 겁니다.


말로는 쉽죠?... 그런데 보통 구현들 어떻게 하셨나요?


흔히 쓰던 광선 vs AABB 충돌검출 방법

제가 흔히 봤던 방법중 하나는 마우스 클릭한 위치부터 화면 안쪽으로 광선(ray)를 쏴주면서 그 광선과 각 물체의 AABB의 충돌검사를 한뒤 가장 가까이에 있는 물체를 선택하는 거였습니다.


예를 들어 아래 이미지에서 오른쪽 가장자리가 화면이라고 가정하면 이런식으로 ray를 쏴서 aabb를 찾는거죠.



그런데 이 방법에 문제들이 좀 있습니다

  • 월드에 물체들이 많으면 충돌검사 시간 꽤 걸립니다

  • AABB와 충돌검사를 하므로 픽셀단위로 정확한 충돌검사가 불가능합니다.






제가 쓰는 렌더타겟과 물체 ID를 이용한 방법

저는 GPU를 이용해서 위 문제점들을 해결했습니다. 알고리듬은 매우 간단합니다. 자세한 코드는 위에 첨부해 놓은 예제코드를 봐주세요.

  1. 각 물체마다 고유 해쉬 아이디(32비트 정수)를 부여한다.

  2. 화면크기와 동일한 A8R8G8B8 렌더타겟을 하나 만든다. (이후 ID맵이라 부름)

  3. ID Map맵 렌더타겟을 설정한다.

  4. 모든 물체를 그려주면서 물체 해쉬(32비트)값을 8비트씩 짤라 R,G,B,A채널에 써준다

  5. 마우스가 클릭된 위치의 픽셀을 읽어온다

  6. 그 해쉬값과 동일한 물체를 선택한다.

  7. 선택된 물체로 하고 싶은 짓을 한다 -_-

  8. 끝 -_-


해쉬아이디

해쉬 아이디는 아무렇게나 생성이 가능합니다. 각 물체마다 고유하기만 하면 되죠. 제 예제에서는 그냥 물체 이름인 string으로부터 해쉬 아이디를 생성했습니다.


해쉬아이디를 색상으로 바꾸는 법

해쉬 아이디를 RGBA로 바꾸는 코드는 다음과 같습니다.


private static Color HashIDToColour(int hash)

{

    int a = (hash >> 24) & 0xff;

    int b = (hash >> 16) & 0xff;

    int g = (hash >> 8) & 0xff;

    int r = hash & 0xff;


    return new Color(r, g, b, a);

}


이 후 이걸 셰이더 함수로 대입해준 뒤


ColourFX.Parameters["Colour"].SetValue(HashIDToColour(go.Hash).ToVector4());


셰이더 안에서 다음과 같이 그려만 주면 됩니다.

float4 ps(VtxOut In) : COLOR

{

 return Colour;

}


해쉬아이디 읽어오기

매우 간단합니다. 그냥 그 픽셀값을 32비트로 읽어오면 끝입니다. (이미 해쉬 ID에서 색상으로 변환할때 byte순서및 엔디안 문제를 고려했거든요


public int PickObject(int x, int y)

{

    int hash = Hash.INVALID;


    int [] pickedPixel = new int[1];


    IDMap.GetData<int>(0, new Rectangle(x, y, 1, 1), pickedPixel, 0, 1);


    hash = pickedPixel[0];


    return hash;

}


예제 결과

일단 제 샘플 코드를 실행해보면 다음과 같은 그림이 보일겁니다.


메인 화면에 3개의 공이 있고.. 오른쪽 아래는 ID맵입니다.


여기서 파란색 공위에 마우스를 클릭하면 다음과 같이 됩니다.


현재 선택된 물체를 노란색으로 표현했습니다. 그리고 현재 선택된 물체를 ID 맵에 안그려서 다시 한번 더 클릭을 하면 그뒤에 있는 물체가 대신 선택되게 만들었습니다.



이정도면 대충 보여드린듯 하죠? 자세한건 직접 받아서 실행해보세요.. -_-;


기타 응용

최근에 이 기법을 응용해서 물체 ID 대신에 물체의 깊이를 저장도 해봤답니다. 마우스 클릭 위치 근처에 있는 복셀(voxel)들을 전부다 고칠일이 있어서... 그냥 마우스 클릭 깊이만 찾아다 그로부터 월드위치 구한 뒤, octree를 뒤져서 근처에 있는 복셀들을 찾아냈죠.


기타 등등의 응용법이 있을 겁니다.




오랜만에 글써본 포프였습니다.



반응형
,
Posted by 대마왕J

어서와

 

 

 

아 두 달 만에 쓰니까 막 게을러 질라구 그래 ㅋㅋㅋ

하여간 정~~~~말 오래 기다리셨습니다. 제가 슬슬 게을러지는 데다가 몸도 말을 안들어서 (... 위로 댓글 달기만 해봐라) 막 매일 밤새서 글 작성 그런거 못해요. 회사 프로젝트도 바빠지고 있구요. 게다가 줄여나가려 노력하고 있는데 자꾸 거절할 수 없는 강의 / 강연 요청이 들어와서요 ...

삼X지를 품X는 잘 오픈한 것 같은데... 저는 지금 거기 없어요. 제가 보는 프로젝트가 하나가 아니랍니다 (...) 
삼품 팀원들은 다들 미쳐가고 있는 모양이지만요. 모바일 연동게임 만드는거 보통 어려운 일이 아니거든요.
모바일 프로젝트 손대고 싶은거 한 두 개가 아닌데 더 못챙기고 올라온게 못내 아쉽...

 

열심히 코딩중인 프로그래머 아이맥 군

자 그럼 오늘 하던 거나 해 봅시다.

제 강의 스타일은 '반복' 이예요.
어차피 새로운 내용 공부할 때 한 번만에 다 이해하는 사람은 거의 없거든요. 저도 그래요. 제 학생들도 다 그랬구요 후후후 . 그래서 저는 계속 같은 내용으로 응용해서 반복시켜요.

그러다가 아하! 하고 뿅 전구가 들어오는 학생들이 생기면 기쁘죠.

유레카!

그 친구들은 갑자기 머릿속이 환해지는 거구요. 대충 살아가지만 나름 강의할때 학생들이 이해하는 기전(메카니즘)을 연구해서 노력하고 있답니다. 뭐 이런 얘기를 왜 하는지는 앞으로 보시면 잘 아실테고...

 

 

 

0. 오늘은 일단 지난 시간 얘기 잠깐

지난 번에 하프 램버트라는게 있었습니다. 먼 옛날 옛적에요. 네에 그런게 있었어요. 호랑이 담배피던 때 말이죠.

 

그랬어요.


어쨌거나 지난 번 시간은 이런 결과물을 만드는 거였습니다.

이게 최종 결과물이구요. 원래 원본은 ...

이게 그러니까.. 지금 저 0.5 라고 되어 있던 부분이 사실 0이었죠.


지금 0이라고 되어 있던 부분은 사실 -1 이었구요.

거기다가 마법의 공식인 *0.5+0.5 라고 하는 '매직 넘버' 를 넣어서 저렇게 만든거구요.

이 매직 넘버를 넣기 전의 그림은 아세요?  기억하시죠?

이게 원본이었잖아요.

Dot 공식인가 뭔가에다가 조명벡터와 노말벡터(서피스 벡터)를  넣으면.. 코사인 그래프에 따라서 저런 값이 나오게 되어서.. 빛이 비추는 것처럼 보이게 된다는게 기본이었죠.

이게 중요한 그림이란 말입니다.

 

그래요.우리는 지난 시간에 이걸 가지고 하프-램버트 (Half-Lambert) 라고 하는 빛 계산 공식으로 살짝 바꿔 봤어요.
어렵지 않고 쉬웠죠? 네 그래요. 쉬운게 당연하죠. 이거 진짜 쉬운 공식이거든요.

 

 

1. 그래서 이번 시간에는 다시 여기서부터 시작합니다 .

 

짜잔

반복이당

 

흔한 반도의 램버트.jpg

자자 좋아요. 자꾸 반복하니까 그림 안만들어도 되고 좋네...

이제 저건 아시겠죠? 중요해요!!! 조명 벡터와 노말벡터로 dot 연산해서 음영만드는거요!!! 중요하고 중요하고 또 중요해요!! 앞으로 2강 정도는 저것만 가지고 놀거라고요!!!

 

하나가지고 계속 울궈먹는건 정말 멋져요!

 

 

자 그럼 잘 생각해 보죠.

흐음. 조명 벡터[각주:1]노말 벡터[각주:2]를 ... 그래.. 둘 가지고 닷인지 뭔지 계산하는거...  알겠구나..

근데 말이죠. 잘 생각해 보세요. 이렇게 한번 생각해 보세요.

내가 말이죠. 내가... 만약에....

 

저 조명을 들고 있는거야 .

이렇게.

 

 

 

그럼 내가 조명을 들고 있으니까... 내가 볼 때는 저 주전자가 어떻게 보이겠어요?

 

 

어떻게 보이기는요. 이렇게 보이죠.

내가 조명이니까 , 내가 보는 방향에서 조명이 나간다고 치고 계산하는 거니까 이렇게 보이죠.

 

... 어라..

잠깐 재미있는 생각이 났습니다.

뭐냐면.

 

dot (조명벡터 , 노말벡터) 의 연산을

dot (카메라 벡터[각주:3], 노말벡터) 로 바꾼다면??

 

분명히 카메라에서 조명이 나오는 건 아니지만, dot연산으로 빛이 들어오는 음영을 '그리고' 있는 거니까... 사실 컴퓨터가 조명벡터일지 카메라 벡터일지 압니까. 그냥 float3만 들어오면 걍 dot 연산해주고 그러는 거지....

그래요 위에 보인 저 그림처럼, 내가 "굳이 카메라를 돌려서 라이트와 같은 방향으로 맞춰서 볼 필요도 없이" 자동으로 위와 같은 그림이 나올 겁니다.

일단 해보지요. 이해 안되시는 분도 따라해 보세요.

 

우선 이것부터 시작해야겠지요. 이거 모르시는 분은 저번 시간으로 돌아가서 다시 공부하고 오세요.
앞에 설명한거 이해 못한 채 뒤에것 공부할 수 있는 그런 단계 아닙니다 이제.

자 여기에서 아까 말한대로, 조명벡터(Light Vector) 를 카메라 벡터(CameraVector) 로 바꿔줘 볼께요.

 

어디 찾아 봅시다... 이 벡터는 있는걸 받아오는 거니까 Input에 있을테고...
어라? 여기에서의 이름은 카메라 벡터가 아니고 시선벡터 (Eye Vector) 네요.
어차피 다 같은 뜻이니까 당황하지 말도록 합시다.

 

와우 시선벡터 (Eye Vector)가 나왔군요.
역시나 아이콘 짱 좋아 ㅋㅋㅋㅋ 아이콘만 보면 카메라 벡터인줄 누구라도 알 수 있겠죠?

특히나 여기에 쓰는 벡터들은 기본적으로 정규화 (Normalize : 노말라이즈) 되어서 들어오기 때문에 아무 생각 없이 쓰기 짱 좋습니다.[각주:4]

이제 간단합니다. 시선벡터를 조명벡터 대신에 사용해 봅시다.

자아... 마치 카메라 (= 지금 당신이 보고 있는 눈) 이 조명인 것 처럼 연산이 됩니다. 당연하죠. 원래 조명 연산이라는게 그냥 벡터끼리의 연산이었으니까 ,굳이 조명을 안넣고 이렇게 아무 벡터나 넣어도 연산되는게 당연하잖아요.

어쨌건 당신의 눈은 이제 조명이 되었습니다.

 

대충 이렇게 된 느낌일까나.

 

 

 

그리고 이왕 하는거, LightColor 를 받아오던 것을 일반 Color로 바꿔 보았습니다. 더 이상 조명과는 이제 인연이 없어요.
조명 지워 버려도 됩니다 저거. 조명 안쓰니까요 안써. [각주:5]

자 , 카메라를 빙글빙글 돌려보세요. 그래도 조명에는 변화가 없습니다. 나를 바라보는 쪽이 언제나 밝아요.
신기하지 않습니까?

 

 

자... 뭐... 그래요. 알겠는데. 이거 가지고 이제 뭘 할 수 있을까요???

 

 

2. 림라이트를 만들어 봅시다.

 

응? 림라이트?

림라이트라고 하는 것은 요즘 게임에서 개나소나 많이들 쓰고 있는, 외각선이 빛나는 후광(後光) 효과입니다.
구현이 간단한데다가 배경과 캐릭터를 분리해 주어서 디테일을 살려주는 등 좋은 점이 많이 있습니다.

림라이트에 대한 이론적 설명은 여기 퐁퐁퐁 아저씨의 블로그 글을 참고해 주세요.

http://blog.naver.com/sorkelf?Redirect=Log&logNo=40135726372

자 솔직히 림라이트는 ... 다 만들었습니다! 위에 이미 설명 다 했어요 !!! ㅋㅋㅋ
조명벡터를 카메라 벡터로 바꾸는게 전부 다 거든요!!!

그럼 이제 이렇게 생각하시는 분들이 있겠죠.

그냥 조명이 카메라로 바뀐건데 뭐가 림라이트라는거야?

 장난하냐

자 과연 그럴까요. 해 봅시다.

 

일단 공식을 적용할 곳은 아직 float3 가 되기 전, 그냥 float 인 저 부분을 공략할 겁니다. float3는 이미 color가 적용되어 있어서 곤란. 그냥 순수하게 float 연산만 나오는 부분이 필요해요. 가끔 저기 Color가 적용된 후에다가 하시는 분들 계신데, 아니예요. 칼라가 적용되기 전에 순수하게 float 데이터가 나올 때 적용하는 겁니다 !!! 잘 생각해 보세요! 당연해요!!

 저 부분을 끊고, 뭔가 공식을 적용합시다 [각주:6]

 

 간만에 꺼내는 NegateOneMinus예요. 기억하시는 분?

 그냥 꺼내기만 해서는 - 만 나오죠. 이건 들어오는 값을 - 로 반전시켜주는 기능이예요.
우리가 여기서 필요한건 1- (One Minus) 입니다.

그걸 저 dot 값에 적용해 보죠.

 

 

 

 

 

 

 

 

 

짜잔.[각주:7]

오오오! 뭔지 알 것 같습니다!

그쵸... 조명을 1- 해줘서 뒤집어 주면... 저렇게 나와야지요!


그리고 흔히 보던 림라이트가 눈에 보이기 시작합니다! 그게 조명에서 시작한 것이었다니! 그냥 조명을 1- 로 뒤집어 주면 되는 것이었습니다! 생각해 보면 일목요연하죠. 조명이 카메라로 바뀌어서, 나를 바라보고 있는 노말벡터 부분의 값이 1이 되어 버리고, 나의 시선과 90도로 꺾인 부분은 0이 되어 버리는건데, 그걸 뒤집어 버리니까 저렇게 결과가 나온 것이었지요. 즉 노말벡터가 내 시선과 90도가 되면 될수록 밝아진다는...

이거 이해하고 넘어가야 합니다. 매우 중요하고 응용도 많이 되어요.

 

좋아요 그럼 이제 끝인가요?

뭔가 좀 부족하죠?

부족한건 일단 저겁니다. 저 림라이트의 두께... 너무 두꺼워요. 좀 얇게 만들어 봅시다.

 

 

 

3. 두께를 조절해 봅시다.

두께를 조절한다... 밝게 있는 부분의 면적을 늘이거나 줄이는 거지요.
음.. 어떻게 하면 될까요?

여기서 추가로 필요한게 pow (x,y) 라고 하는 함수입니다 .
pow(x,y)는 x의 y승이예요.

노드로 꺼내보면 이렇게 꺼낼 수 있죠.

 

shader FX의 노드로는... Raise to a Power 라는 이름으로 되어 있군요. [각주:8]
꺼내봅시다.

 

역시나 모양도 아주 이쁘게 X의 Y승이라고 씌여 있습니다 ㅋ 제가 shaderFX를 교육자료로 쓰는 이유가 저 아이콘 때문이라고 해도 과언이 아니예요 ㅋㅋ

좋아요. 그럼 X의 Y승을 하면 무슨 일이 일어나는건가요?

 

 

수학따위는 개나 줘 버린 우리 머리로 간단히 생각해 봐서 .. 2제곱한다고 생각해 봅시다.

0을 2제곱하면? 0이죠?
1을 2제곱하면? 1이네요?

일단 0과 1은 안변한다는걸 알 수 있습니다. 그 중간이 변하는 거겠죠.

0.5를 2제곱하면? 얼마가 나와요? 0.5 * 0.5 가 얼마냐공.

 

 

... 이러면 가끔 2.5 라고 하시는 분 계시는데요. 아닙니다. 0.25예요 -_-;;;
소숫점은 서로 곱하면 곱할수록 수가 줄어듭니다.

괜찮아요 어린이여러분. 그 나이 때에는 모를 수도 있죠.

 

 

넹 0.5를 2제곱하면 0.25가 된다는걸 알았습니다.

즉 0~1 사이에 있는 모든 수 들은 모두 소수점이니까, 
정수로 제곱하면 제곱할 수록 값이 더 작아진다는걸 알 수 있지요.

좋아요. 그럼 이걸 본격적으로 그래프로 그려보죠. 그럼 이렇게 된다는 말입니다.

 

..이렇게 노가다로 말고 공식으로 그리는 법 없나..

올 ㅋ노가다다 ㅋㅋㅋ  

보시면 알겠지만, 그냥 코사인 공식은 밝기 (1.0 ~0.0) 가 부드럽게 줄어드는데,
3제곱 하고 5제곱 하니까 밝은 부분의 영역이 줄어드는 것을 알 수 있습니다 . 내가 이거하려고 엑셀을 꺼내다니

그래프가 더 날카로워진다는 거죠! 그 말은... 어두운 부분이 늘어난다는 거예요! 그러니까 .. 밝은 부분이 좁아진다는 것!
그렇다면...!!! 그렇습니다. 외각선 두께를 조절할 수 있습니다!!!
[각주:9]

백문이 불여일견. 해봅시다.

 

요걸 하는 거예요.

 

제곱은 한 3제곱을 줘 보도록 하지요. 이렇게 하면 결과는...

 

이게 원래 제곱 안했을때

 

이게 3제곱 한 결과

넵 확실히 얇아졌습니다! 3제곱 해서 얇아졌으니, 5제곱 하면 더 얇아지겠지요. [각주:10]

 

이렇게 만든걸 기존의 라이트의 결과물에 더해(+) 주기만 하면 게임에서 흔히 볼 수 있는 림라이트가 되는 겁니다!
한 번 해 볼까요?

여기서 만든 공식이 프레넬 반사(Fresnel Reflection) 공식의 핵심입니다. 즉 이 공식을 아시면 프레넬 효과를 만드실 수 있다는 말씀이지요. 자세한 프레넬 리플렉션에 대해서는 퐁포퐁 퐁퐁 의  http://blog.naver.com/sorkelf?Redirect=Log&logNo=40157708229 에서 보도록 합니다. 말이 좀 어렵긴 하지만 잘 보다 보면 위 공식이 나옵니다.

좀 더 재미있는 글을 보시려면 실버치매님의 이 글을 보시는 것도 좋습니다 .
http://gamedevforever.com/35

 

4. 응용해 봅시다.

뭐 다 아시는 거니까 이건 하나하나 설명 안할께요.
일단 뭐 아까 지웠던 라이트를 다시 만들어 놔야겠고.. (안지우셨으면 그냥 두시면 되겠죠. 이럴때 쓰려고 지우지 말라고 한것임 ㅋ)

기본 램버트 라이트 공식에 림라이트 공식을 더하는 겁니다.
아참 이건 최종 계산된 칼라값 (float3) 를 더하는 거라는게 중요해요. 
왜 그러는지 이해 안되면 고민해 보세요. 이건 숙제.

 

이거 한 번 해보세요. 우왕 뭔가 많아 보인다.  

결과는 이렇게 되면 성공.

 

사실 저 림라이트는 일종의 '역광' 으로. 빛을 등지고 있어야 보이는 효과이긴 합니다. 지금은 빛을 등지는지 아닌지 신경도 안쓰고 그냥 만들어서 더해 봤지요. 제대로 역광을 만드려면  라이트 디렉션과 내 시선 벡터를 dot 연산해서 90도가 넘어가는 시점에서부터 림라이트가 나타나게 만들면 될 것입니다.

이 힌트만 가지고 해 보실 수 있으신 분이라면, 이 강의는 더이상 듣지 않으셔도 됩니다. 당장 포프님 책으로 렌더몽키를 공부하세요 !!!!

 

뭐 혹은 이렇게 응용할 수도 있습니다.

림라이트 연산이 색상 더하기 전에는 float 이라는 것을 이용해서 , 그걸 알파에 넣어 버린다면..?

 

 요렇게 말이죠. 이렇게 한다면

 

뿅. 크하하하 외각만 남았습니다.
음... 근데 빛 안받는 부분이 검은 외각이 남는게 좀 불만이시면  

 

이렇게 렘버트 연산을 아예 날려 버리시고 그냥 단색으로 처리해 보리는 수도 있지요. 이러면 외각만 빛나는 유령 (Ghost) 효과가 나올 겁니다.

 

 

스타크래프트 2에 나오는 맹스크의 홀로그램도 이걸 응용한 거지요.

 

 

또 다른 응용도 가능합니다. 1- 했던 공식을 없애버리면, 저런 효과가 나와요. 외각 엷어지는 효과 말이죠.
이건 적절한 블렌딩과 함께 이용하면 강화 이펙트 같은데 쓸 수도 있는 효과를 만들 수 있습니다 .

 

5. 결론

넹 오늘은 프레넬 반사 구현을 위한 공식의 핵심을 배워 봤습니다. 사실 이 공식의 장점은 이것 뿐만이 아니예요. 응용은 훨씬 더 많이 할 수 있습니다. 반사와 굴절을 적절하게 섞어서 물 효과를 낸다던가... 외각으로 갈 수록 다른 텍스쳐가 나타날 수 있게 한다던가.. 등등 말이죠. 기본적인 dot 공식에서 시작한 공식이 이렇게 발전한다는것 .. 꽤 매력적이죠?

아직 안끝났습니다. 다음 시간에도 또 이 dot 공식 가지고 놀아보도록 하죠 후후후

그럼 여러분 다음 달 까지 안뇽 >_<  

안뇽안뇽

 

jp16강.SFX


 

ps. 출판사와 shaderFX 책을 내 볼까 하고 회의를 했었습니다만... 아시다시피 최근에 이 shaderFX 제작자가 오토데스크 입사했다고 다운로드 경로 막아놓고 잠수 타 버렸습니다. (...) 덕분에 지금 이 내용으로 책을 쓰려는 기획은 무기한 연기중이예요... ㅠㅠ 혹시 오토데스크 본사에 아시는 분 있으면 연락좀 해주세요 ㅠㅠ 게다가 이 사람이 업그레이드 안하면 2013 버전도 안나오잖아요.. 맥스 2014에는 기본으로 포함된다면 얼마나 좋을까요 ... ㅠㅠ

그래서 제작자와 연락이 되기 전에는 책이 나오기 힘들 것 같습니다. ㅠㅠ 다른 툴을 써 볼까 했는데 솔직히 이것만큼 쉽게 배울 수 있을 만큼 쓸만한 녀석도 없구요.

 

  1. 라이트 벡터(Light Vector) 라고도 불러요 [본문으로]
  2. 서피스 벡터 (surface vector) 라고도 부르더라고요. 이거 원 용어가 많아서.. 일본 번역서에서는 '법선' 이라고도 하지요 [본문으로]
  3. 다른이름으로는 뷰벡터(View Vector) , 시선벡터 라고도 부릅니다. 다 같은 말이예요 [본문으로]
  4. 벡터끼리의 연산을 할 때에는 서로 길이가 다르면 연산에서 잘못된 값이 나오기 때문에 길이를 맞춰주는 작업이 필요합니다. 그래서 길이를 1로 맞춰주는 작업을 정규화 (Normalize) 라고 하죠. 또한 벡터의 길이를 1로 맞추면 연산이 무척 간단해 지기도 합니다. 여기서야 자동으로 해 주지만... 실제로 코딩으로 shader을 짤 때에는 이 Normalize 때문에 이상한 결과가 나오는 경우가 꽤 있습니다. [본문으로]
  5. 지금은 기본 구현을 위해 과감히 라이트를 안씁니다만.... 나중에 쓸 데가 있을 겁니다 .. 아마도... 그러니 굳이 안 지워 놓으셔도 돼요.. [본문으로]
  6. 하지만 여러분들이 벌써 해 본 거라는거. [본문으로]
  7. 가끔 '맞게 했는데 저렇게 안보인다!' 라고 하시는 학생분들 계신데, 혹시 User 뷰로 해놓으신거 아닙니까? Perspective 로 하지 않으면 저 효과가 보이지 않습니다. [본문으로]
  8. 이런 노드의 이름은 보통 hlsl에서 쓰이는 함수의 이름과 '비슷' 하게 되어 있는 경우가 많이 있습니다. 툴마다 조금씩 이름은 틀릴 수 있지만, 어쨌거나 함수명인 'power' 는 꼭 들어가곤 한다는 거죠. 그래서 하나 배워 놓으면 다른 툴도 대충 적응이 가능함. [본문으로]
  9. 이전 시간에 숙제로 내드렸던 pow가 이겁니다 . 실제로 액셀에서도 POWER(x,y) 예요. 숙제 해 오신분 계신지?? [본문으로]
  10. 반대로 0.5제곱 하면 넓어집니다 잇힝 [본문으로]
반응형
,
Posted by 밥을먹는선비

0. 들어가며..


전에 코루틴 예제를 나름 간단하면서도 실용적인 예제를 만들려고했는데 결론은 실패로 끝난거같았습니다. ㅜ.ㅜ;

(참고 : http://www.gamedevforever.com/251 )

그래서 나름 시간날때 마다 고심을해봤습니다.

물론 매우 길게 장황하게 예제를 만들면 되지만 그렇게 해봤자 안그래도 난해한 코루틴에 더 인상만 않좋을거같아서 간결하면서도 쉬운예제를 고민을 해봤습니다.

그러다가 불현듯 안철수후보의 사퇴 연설을 듣던중 갑자기 스치는 생각이 있어서 짧게 정리 해보았습니다.


1. 문제의 정의


예전에 실용적이지 못했던게 Destroy 함수에 두번째 인자에 시간값을 두어 객체가 파괴되는 시간을 조절할수있었는데 사실 굳이 코루틴을 쓸필요는 없었습니다.

그래서 이번에는....


두둥!~~...



....시간이 아니라... 


"거리"......로 바꾸어보았습니다.


...


생각 해보니 좀 억지 스럽기도 하네요 ㅡ.ㅡ;;


2. 대기 함수 만들기


전에 kgc강의에서도 했던 이야기인데요. 사실 비동기 처리때문에 쓰레드를 쓰고 막상 쓰레드가 하는일은 기다리는 일이라는 아이러니가 있다는 말씀을 드렸습니다.

대부분의 코루틴은 그래서 대기 관련 함수입니다.(꼭 대기는 아니더라도 먼가 기다려야하는 것과 관련이 많은 일이죠. 그래서 어느 질문자분의 말씀처럼 io도 그중에서 가장 흔한 예중에 하나고요) 사실 대기하는 동안 넌블럭 상태를 유지하려고 코루틴이나 쓰레드를 쓰는것이죠.


암튼 그래서 .... 


일정 거리까지 날라갈때까지 끝나지 않는 함수를 일단 만들어 봅시다.


function WaitDist(dist_limit:float,speed:float) {

   var total_dist:float = 0;

   var loop:boolean = true;

   while(loop) {

     total_dist += Time.deltaTime * speed;

     if(total_dist > dist_limit) {

       loop = false;

    }

  }

}


이렇게 함수를 만들고 


WaitDist(유효사거리 , 탄속); 


이런식으로 호출해주면 블럭 상태에 걸리고 말겠죠.


3. 넌 블럭킹을 위한 양보구문


이전에 만들었던 함수에 다음과 같이 몇가지를 추가해줍니다.


function WaitDist(dist_limit:float,speed:float) {

   var total_dist:float = 0;

   var loop:boolean = true;

   while(loop) {

     total_dist += Time.deltaTime * speed;

     if(total_dist > dist_limit) {

       loop = false;

    }

    yield;

  }

}


바로 이와같이 루프문 끝부분에 빨간색 양보 구문을 추가해줍니다.


그리고 호출할때 다음과 같이 해줍니다.


yield WaitDist(유효사거리,탄속); 


이렇게 해주면 WaitDist함수가 끝나기 전까지 그다음 라인으로 실행이 넘어가지않지만 그렇다고 블럭 상태에 걸리지도 않습니다.

(자세한 흐름은 이전 강의를 참고해주세요.)


그 다음 라인에서 아래와 같이 해서 객체를 지워주면됩니다.

Destroy(this,gameObject);


4. 결론 & 전체 소스


사실 이번에도 코루틴을 사용하지않은 코드와 비교할때 예제는 코드량이 극단적으로 줄거나 그러지는 않습니다만...


그렇지만 코루틴을 사용하면 Update함수에서는 단순히 객체를 그냥 날라가는것에 중점을 두어 구현 할수있습니다. 그래서 지우는 코드를 만들기위해서 추가적으로 비교구문같은것이 붙지않기때문에 오직 날라가는 효과에만 집중할수있어서 그것도 장점이 될 수 있을거 같습니다













반응형
,
Posted by Junios

유니티3D 새버전에 추가 된 Mecanim 애니메이션 시스템의 간단한 사용법과 활용 방법입니다.

별거 아니지만 도움이 되길 바라며~

첫 글 쓰는건 떨리는군요 ㄷㄷ



MecanimSample.z01


MecanimSample.z02


MecanimSample.z03


MecanimSample.z04


MecanimSample.z05


MecanimSample.zip


샘플로 만든 프로젝트인데 한번에 안 올라가서 쪼개서 올립니다.

반응형
,