[워3 에디터 강좌] 논리값 변수의 이해 by storm


지난 강좌에서는 정수형(integer) 변수를 활용하는 방법에 대해서 알아보았었다. 이번에는 그에 이어서 논리값을 변수로 선언해서 활용하는 방법을 살펴보도록 하자.

논리값이란 프로그래밍에서 말하는 부울(boolean) 타입의 변수를 의미한다. 이것은 참(true) 또는 거짓(false)의 두 가지 정보만을 저장할 수 있는 변수 타입이다.
▶예제맵 다운로드: TriggerEX_09.w3x

워3 에디터에서 예제맵을 열어보면 플레이어의 영웅 유닛 아서스가 있고 그 앞에 돌 문이 닫혀져 있다. 그리고 문 안쪽과 문 너머에 레버(지렛대)가 하나씩 있을 것이다. 그러면 트리거를 통해서 플레이어가 레버를 당겨서 문을 열고 닫을 수 있게 설정해보도록 하자. 일단 아래와 같이 이벤트/조건/액션을 짜본다. 이 트리거는 레버가 작동할 때 벌어질 일들에 대해서 설정하는 것이므로 트리거 이름은 Lever Activated로 해두자. 단, 워크래프트3에서는 장치가 따로 작동하는 기능이 없기 때문에 실제로는 레버가 있어도 밀거나 당기는 개념이 아니라 공격해서 파괴시키면 레버를 작동한 것으로 판정한다. 그래서 이벤트에서는 '장치 파괴'를 써야 한다. 구르는 돌 문을 열고 닫는 것도 마찬가지로 파괴시키면 문이 열린다.

  • 이벤트
    장치 - 지렛대 0001 <생성>이 장치가 파괴되면 작동합니다
    ▷ 이벤트 종류 - 장치 항목에서 '장치가 파괴되면 작동' 선택
    ▷ 장치 클릭 후 [나무/파괴 가능 물체 선택] 버튼을 누른 다음, 맵 상에서 문 앞의 지렛대 클릭

  • 조건
    없음

  • 액션
    장치 - 구르는 돌 문 (수평4) 0000 <생성>을 파괴합니다
    ▷ 액션 종류 - 장치 항목에서 '장치 파괴' 선택
    ▷ (마지막으로 생성된 장치) 클릭 후 [나무/파괴 가능 물체 선택] 버튼을 누른 다음, 맵 상에서 '구르는 돌 문' 클릭
이와 같이 트리거를 짠 다음 플레이를 해보면 플레이어가 문 앞 지렛대를 파괴했을 때 구르는 돌 문이 열릴 것이다. 좀 더 그럴듯하게 만들려면 액션 맨 위에 약간의 대기시간을 주고, 돌 문이 열릴 때 어울리는 사운드를 넣는다. 완성된 예제맵에서는 게임시간으로 0.25초를 대기하고, BattlenetBirth1.wav 라는 사운드를 삽입하였다.

게임시간으로 대기 액션은 액션 카테고리에서 일반 항목에 있으며 사운드 삽입은 사운드 카테고리에서 사운드 재생에 보면 나온다. 삽입할 사운드는 예제맵 상에 미리 넣어두었으니까 단축키 F5를 눌러서 사운드 에디터를 열고 미리 들어보면 된다. 트리거에 사운드를 삽입하는 방법을 잊었다면 강좌 4편을 참고하라. http://sstorm.egloos.com/4944934

자, 여기까지는 별로 어렵지 않다. 에디터 강좌를 1편부터 쭉 보고 따라해봤다면 충분히 이해할 수 있는 수준이다. 하지만 문제는 지금부터다. 레버를 당겼을 때(파괴 했을때) 문이 닫혀있는 경우에는 열게 하고, 열려 있는 경우에는 닫히게 하려면 어떻게 설정해야 할까?

구르는 돌 문이 열려 있냐 닫혀 있냐 상태의 구분을 위해서 논리값으로 변수를 선언해야 한다. 여기서는 문이 닫혀있는 경우를 FALSE, 열려 있는 경우를 TRUE로 설정하도록 한다.

변수를 만들기 위해서는 트리거 에디터 상에서  Ctrl + B를 눌러서 변수 편집창을 연 다음 새로운 변수 만들기(Ctrl + N)에서 변수 이름을 짓고 변수 종류를 골라야 한다. 여기서는 변수 이름을 GateOpened로 하고 변수 종류는 논리값 (boolean)으로 설정한다. 그런데 초기값은 무엇으로 해야 할까? 처음에 문이 닫혀 있는 상태이므로 초기값은 FALSE로 해야 맞다. 반대로 만약 처음에 문이 열려 있는 상태로 시작한다면 초기값이 TRUE여야 한다.


그러면 위에서 만든 Lever Activated 트리거에서 새로운 액션 만들기(Ctrl + R)를 한 다음, 일반 항목에서 If / Then / Else (다중 함수)를 하나 만든다.

이제 여기에서 If - 조건에 들어갈 조건을 설정해야 한다. 조건은 무엇일까? 레버를 작동시키면(파괴하면) 문이 열려 있는지 닫혀있는지를 체크해서 문이 열려 있는 상태면 닫아야 하고, 닫혀 있으면 열어야 하므로, 좀전에 설정했던 논리값 변수 GateOpened 가 TRUE인지 FALSE인지를 따져봐야 한다. 그래서 이 값이 TRUE 이면 문이 열려 있다는 얘기므로 닫아줘야 하고, FALSE이면 문이 닫혀 있다는 얘기므로 열어주면 된다.

If - 조건 항목을 클릭한 상태에서 새로운 조건 만들기(Ctrl + D)를 하면 기본값인 논리값 비교 항목이 선택되어 있을 것이다. 그러면 여기서 ((트리거를 작동시킨 유닛)(은)는 건물임) 을 클릭한 다음 변수 항목에 있는 GateOpened 를 선택하자. 그러면 조건 텍스트가 GateOpened == (서로 같다) TRUE 로 바뀔 것이다.


그러면, 이 트리거는 레버가 작동할 때(파괴될 때) GateOpened라는 변수의 값을 체크해서 그 값이 TRUE면 Then에 있는 액션을, FALSE면 Else에 있는 액션을 실행하게 된다. 즉 이 트리거의 경우 GateOpened의 값이 TRUE면 문이 열려있다는 얘기므로 Then 항목에서는 문을 닫는 액션이 들어가야 한다. 반면에 ElseGateOpened의 값이 FALSE, 즉 문이 닫혀있는 상태에 해당하므로, 문을 여는 액션들이 들어가야 한다. 문을 여는 액션은 이미 만들어놓았으므로 아래 그림과 같이 그 액션들을 Else 항목에 옮겨놓는다.

그러면 이제는 문을 여는 액션을 Then 항목에 넣을 차례다. 게임 시간으로 대기 액션과 사운드 재생 액션은 Else에 있는 것을 그대로 복사해서 붙여넣기 하면 되고, 문을 여는 액션은 장치 카테고리에서 장치 부활을 선택한 다음 부활시킬 장치를 구르는 돌 문으로 지정해주면 된다.

장치 - 장치 부활 액션의 액션 텍스트에서 (마지막으로 생성된 장치)를 클릭한 다음, 변수 항목에서 구르는 돌 문을 지정해 준다. 그리고 그 아래 줄에 있는 ((마지막으로 생성된 장치)의 최대 체력)을 클릭한 다음, 함수(F): 장치 - 장치의 최대 체력 아래에 있는 (마지막으로 생성된 장치)의 최대 체력을 클릭하고, 마찬가지로 변수 항목에 있는 구르는 돌 문을 지정하면 된다. 부활 애니메이션은 표시 상태를 그대로 두면 된다.

자, 그러면 이제 다 된 것일까? 그렇지 않다. 액션에서 돌 문을 열고 닫을 때마다 돌 문의 상태를 저장해놓는 변수 GateOpened의 값을 바꿔줘야 한다. 그렇지 않으면 GateOpened의 값이 항상 초기값 FALSE로 고정되어 있기 때문에 트리거는 항상 문이 닫혀있는 것으로 판단하여 문을 여는 액션만 실행할 것이다. 그러므로 문이 한 번 열린 다음에는 아무리 레버를 작동시켜도 그냥 열린 상태로 유지된다.

따라서 새로운 액션 만들기(Ctrl + R)를 해서 일반 카테고리에 있는 전역변수 설정에 간 다음 변수 GateOpened를 바꿔서 선언해줘야 한다. 즉 Then - 액션에서는 문을 닫는 것이므로 GateOpened의 값을 FALSE로 선언해야 하고, Else - 액션에서는 GateOpened를 TRUE로 선언해야 한다.


여기까지 트리거를 설정한 다음 테스트 플레이를 해보자. 그러면 레버를 작동시킬 때 구르는 돌문이 열릴 것이다. 그런데 문제가 있다. 레버를 한 번 작동하면 더 이상 작동시킬 수 없기 때문이다. 앞서도 언급했듯이 워크래프트3에서는 장치를 파괴하면 작동시키는 것으로 간주하기 때문에 따로 장치를 부활시키지 않으면 단 한 번만 작동하고 만다. 그러므로 이 트리거의 경우 레버를 부활시키는 액션을 따로 넣어줘야만 한다.

 
이 액션은 장치 카테고리에서 장치 부활을 선택한 다음 (마지막으로 생성된 장치)(을)를 ((마지막으로 생성된 장치)의 최대 체력)의 체력으로 부활시킵니다 에서 (마지막으로 생성된 장치)를 클릭한 다음 함수(F): 항목에서 이벤트 응답 - 죽은 장치로 설정하고, ((마지막으로 생성된 장치)의 최대 체력)을 클릭한 다음 함수(F): 장치 - 장치의 최대 체력 아래에 있는 (마지막으로 생성된 장치)의 최대 체력을 클릭한 다음, 새로 뜬 창에서 함수(F): 이벤트 응답 - 죽은 장치로 설정한다. 여기서 말하는 이벤트 응답 - 죽은 장치란 장치 죽음(파괴)을 이벤트로 하는 트리거에서 죽은(파괴된) 장치를 지정하는 것을 뜻한다. 그러므로 이 트리거에서 이벤트 응답 - 죽은 장치란, 작동된(파괴된) 레버를 지칭하는 셈이다. 그리고 장치 부활 액션 위에 약간의 대기 시간을 주는 것이 좀 더 그럴듯해 보이므로 참고하라.

참고로, 이와 같이 If / Then / Else 다중 함수를 써서 액션을 복합적을 구성할 때 Then 이나 Else에 있는 액션들은 If에서 설정한 조건에 따라 둘 중 한 쪽의 액션만 실행되지만 함수의 바깥쪽에 있는 액션은 그와는 상관없이 실행된다. 즉 위 트리거에서 맨 아래쪽에 있는 두 액션 - '게임 시간으로 2.00초 대기'와 '장치 - 죽은장치 부활'들은 If / Then / Else 다중 함수의 결과와는 무관하게 실행된다는 뜻이다.

자 그러면 이제 마지막 한 가지만 남았다. 돌 문 너머에 있는 레버를 작동시킬 때에도 문 앞의 레버와 똑같은 기능을 하도록 만들어야 한다. 가장 무식한(?) 방법은 트리거를 통째로 복사해서 이벤트만 바꿔주는 것이다. 하지만 굳이 그렇게 할 필요가 없다. 지금 이 트리거에서 이벤트를 하나 더 추가한 다음, 돌 문 너머에 있는 레버로 바꿔주면 그만이다. 왜냐하면 트리거에서 이벤트가 여러 개인 경우, 그 중 하나의 이벤트만 발생해도 트리거가 작동하기 때문이다. 하지만 조건이 여러 개인 경우에는 모든 조건에 다 맞아야 만 액션이 실행되므로 주의해야 한다.


지금까지 설명한대로 트리거를 잘 설정했다면, 어떤 레버를 작동시키든 돌 문이 정상적으로 열고 닫힐 것이다. 만약 잘 안 된다면 완성된 예제맵을 보고 참고하도록 하라.

▶완성된 예제맵 다운로드: TriggerEX_09_done.w3x


덧글

  • 안녕하세요 2009/07/28 06:09 # 삭제 답글

    강좌잘보고있습니다 ^^;

    래버부활을 설명하시기전에 연습플레이를해보다가

    반대편레버가 작동하지않길래 혼자 뭐가문젠지 끙끙앓다가

    반대편레버는 다른 오브젝트란걸깨닫고 문의글을 쓰는데

    아차 뒤에 다 설명해주시는군요

    혼자 멋대로 진행해서 낭패봤습니다ㅋㅋ..
  • ㅎㅎ 2009/08/08 00:11 # 삭제 답글

    강좌 모두 잘보았는데 이것으로 모든강좌는 끝인가요 ^^?

    더많은 정보를 얻고싶네요 ^^
  • ATree 2009/08/23 18:40 # 삭제 답글

    강좌 잘 보았습니다. 다른 것보다 유독 논리값 변수에 관한것은 확실히 이해하고 연습해야겠네요 (붙여넣기 신공이 아닌 ㅋ) 다음강좌도 정말 궁금합니다. 감사합니다 스톰님 ^^
  • !!! 2010/01/29 10:34 # 삭제 답글

    이러케되면 Then쪽으로 못넘어가지 않나여?
    왜냐면 초기값은 FALSE니까 Else로 넘어가고 계속 TRUE로 변경되잖아요;
  • storm 2010/01/29 13:10 #

    초기값이 FASLE니까 else쪽으로 가서 TRUE가 되고 그다음 다시 하면 TRUE니까 Then으로 가서 FALSE로 바뀌고... 이게 반복되는거죠.
  • 학생 2010/09/01 18:14 # 삭제 답글

    이벤트 - 플레이어가 [레버] 공격
    조건 -
    액션 - 만약 레버가 True상태(비파괴)일때, 문을 열고
    레버가 False상태(파괴)일때, 문을 닫는다.

    라는 식의 방법은 없는 건가요? 이런 방식도 해보고 싶었는데 아깝네요.

    강의 감사합니다. 이제 담편으로...+_+/
  • 기획자 2014/03/21 15:25 # 답글

    워3 에디터는 처음이라 하나씩 따라하고 있는데 정말 친절하고 알기 쉽게 설명해주셔서 감사합니다.
댓글 입력 영역



통계 위젯 (화이트)

2917
177
502137