상세 컨텐츠

본문 제목

적이 아닌 이벤트 만들기 (충돌판정 개선)

제작 이야기/제작 기록

by 안말이 2019. 11. 7. 17:33

본문

※ 제작 기록은 개인 기록 용도로 쓰이기 때문에 반말로 적고 있습니다. (__) 그런데 오늘은 좀 아닐 수도 있습니다.

 

 처음 이 전투방식을 작업할 때는 맵에 존재하는 이벤트는 오로지 적만 있게 할 생각이었기 때문에 별도의 적을 구분하는 처리가 필요 없도록 할 생각이었지만, 막상 튜토리얼을 제작하다 보니 적이 아닌 예외 이벤트가 필요한 상황에 부딪쳤다.

 

 디자인 할 때부터 워낙 이런 변수들에 민감하게 만들어놔서 뭔가를 뜯어고칠 필요가 없을 거라 믿고 과감하게 뛰어들었다.

 

 먼저 예외 이벤트를 크게 2가지로 구분 지었다.

 

1. 플레이어와 직접적으로 접촉판정을 내는 이벤트

     (튜토리얼의 발동 이벤트 혹은 적용할 지 모르겠으나 적의 스킬 탄막 이벤트 등)

2. 갑작스레 생겨나는 이동 불가 장애물(벽 등) 이벤트

 

 

 

 게임이 알만툴의 기본 점프를 베이스로 삼다보니 맨땅에 자체제작한 충돌판정을 만들 때 두 가지의 처리 방식이 달라지게 됐다. 기본적으로 통행 불가능한 지형에 접촉 시에는 바라본 방향을 향해 제자리 점프를 하도록 만들었기 때문이다.

 

 여기서 점프(이동) 직전에 이동하고자 하는 장소에 이벤트가 존재한다면 적으로 인식하고 공격하도록 만들었는데, 적의 번호는 맵 별로 고유 ID를 할당해둔 기능 덕분에 적으로 인식하지 않게 처리하는 것은 간단했다. 어디까지나 기본공격에 한정한 이야기이지만...

 

 위와 같은 직접 접촉 판정 이벤트의 문제점은, 적으로 인식하지 않을 수는 있지만 이벤트 내의 Player touch 판정을 내기가 힘들다는 것이었다. 그렇다고 커먼이벤트에 접촉 판정 이벤트마다 이벤트 번호를 받아다가 별도의 처리를 넣어줬다간 커먼이벤트의 스크롤 때문에 정신 없기 때문에 Player touch 판정이 나는 평범한 이벤트로 구현해야 할 필요가 있었다. (물론 기본 이벤트가 below로 설정된 경우는 점프로도 접촉 판정이 발생한다. 이 사례는 플레이어와 동일한 레이어에 속한 Same as Characters의 처리의 문제)

 

 다행히 이 해결책은 3분도 채 지나지 않아 떠올릴 수 있었다. 그도 그럴게, 사실 터치를 하려면 해당 이벤트에게 이동해 접촉하면 된다. 다만 기능을 막아놨기 때문에 강제로 그렇게 해야했다.

 

 해당 타겟이 적이 아닌 경우 another_target이라는 스위치를 작동시키게만 처리하고, 동작 이벤트에 위와 같은 처리를 끼워넣는다. 이벤트의 판정이 플레이어와 동일이기에 움직임은 어차피 skip처리 되니 조금이라도 처리를 빨리 하기 위해 이동 루트 설정에는 skip을 붙여줬다. (테스트 해보니 확실히 빨랐다.) 이후 라벨 점프로 적이 맞는 경우의 스킵을 처리해준다.

 

 1번의 문제는 이렇게 처리하는 것으로 다음과 같은 작동을 보여준다.

좁은 길목을 지나서 위치한 Same as Characters 이벤트

 

 

 

이 이벤트가 작동할 때는 플레이어가 다음 칸으로 점프나 제자리 점프를 하지 않는다.

 

 1번의 경우는 깔끔하게 정리 됐다. 다음은 2번인 장애물 이벤트의 문제, 이쪽은 지형과 동일한 이벤트이기 때문에 이 이벤트를 감지할 경우 지형과 동일하게 봐줄 것을 처리해야 했으나, 모든 처리가 병렬 없이 대놓고 순차적이기 때문에 점프 전에 '얘는 지형임!' 해버려야 한다.

 

 약간의 시행착오를 겪다가 처리한 방법은 의외로 1번보다 더 단순했다.

 

그냥 another_target을 처리한 조건 분기 그 외의 경우에 똑같은 방식으로 제자리 점프 처리만 넣어줬다.

 당연한 얘기지만, 이렇게만 판정하면 이벤트 고유 ID를 인식하기 때문에 당근 빠따 벽 이벤트가 작동하기 전부터 가까이 갈 수가 없는데 벽은 원래부터 맵 구석 플레이어가 갈 수 없는 장소에서 소환하는 형식 이벤트이기 때문에 이론상 진입 전에 막힐 일은 없다.

 

요약하면 이렇다는 뜻

 

 그런데 나중에 테스트 해보니 첫 이벤트 페이지를 빈 페이지로 두지 않고 스위치 조건을 걸어주면, 이벤트가 그 순간 생성된다는 개념이라 막히질 않아서 딱히 소환할 필요도 없었다. (물론 밑에 얘기할 거지만, 스킬로 넘어가면 얘기가 달라지기 때문에 이 방식은 유지했다.)

 

실제 작동

 

 이걸로 이동과 기본 공격의 처리는 깔끔하게 끝난다. (위에 설명이 좀 부족할 수도 있지만, 게임의 특징상 이동을 하기 전에 적이 있다면 이동이 아닌 공격으로 전환하기 때문)

 

 문제는 스킬의 타겟 판정이 살짝 별도라는 점.

 

대충 이대로 두면 이렇게 된다는 뜻인데... 어? 이거 나중에 부술 수 있는 벽도 만들면 이쁘겠다.

 

 예외 판정을 하는 일 자체는 어렵지 않았다. 사전에 고유 이벤트 번호를 전투 맵마다 유동적으로 할당받아 적인지 아닌지 여부를 판정할 수 있는 기능은 존재하기 때문에, 이 외의 처리를 모두 0으로 반환해 없도록 해주면 될 일이다.

 

미리 만들어둔 할당 번호 처리, 모든 스킬은 한 번에 최대 타겟이 10을 넘지 않으므로 넉넉잡아 10까지 인지하게 해두었다.

 

 예외 처리 이후에는 다시 1번과 2번에 따라 갈리는데, 1번의 경우는 예외 처리를 하는 것만으로도 끝이난다. 지형지물 판정이 아니기 때문에 스킬의 범위표시가 출력되지 않을 이유가 없기 때문!

 

 하지만, 2번인 장애물 이벤트라면 얘기가 다르다. 지형지물과 동일한 판정이기 때문에 스킬의 범위표시가 막혀야 한다. 범위 또한 0인 경우 다행히 바로 방금한 예외처리를 이용하면 된다!

 

 범위 판정은 이벤트를 전혀 의식하지 않는 check_passage를 이용해 0(false)인 경우 통행 불가능한 지형지물, 1(true)인 경우 가능한 지형지물로 판단해 범위를 표시하기 때문에 별도로 이벤트를 위의 39번 변수인 스킬 범위가 적의 ID를 가지고 있지 않은 경우, 범위 판정 또한 적이 아니라고 판단하여 0으로 처리하는 기능을 추가해주면 된다.

 

처리는 복붙도 해야하고 수정 여지가 많으므로 별도의 커먼이벤트로 생성

 

기본 공격 처리와 변수 사용하는 건 같으므로 기본 공격의 타겟 예외 처리를 가져와 추가로 벽인 경우 범위판정만 0을 붙여줬다.

 

 이렇게 처리를 해서 완벽한...줄 알았는데!!!

 생각치도 못한 문제점이 있었으니, 공통 이벤트가 공통 이벤트를 불러오는 딜레이가 생각보다 좀 있다는 것이다. 하나의 공통 이벤트에서 구문을 모두 처리하면 동시에 발동하는 것처럼 빠른 연산이 이루어지지만, 커먼 이벤트는 그렇지 않은 모양이다.

 

 이게 범위 표시 공통 이벤트에 무슨 효과를 가져오냐면...

 

하단에서 스킬을 쓰는 것만 보면 된다.

 보는 것처럼 범위가 한 번에 촥 생성되지 않고, 미묘한 딜레이가 생기게 된다. (범위에 빈 칸이 생기는 건 벽 이벤트를 의도적으로 가져다 놨기 때문)

 우측에서 스킬을 쓰는 건 아직 공통 이벤트의 호출이 없는 상태로 비교용으로 붙여놨다.

 

 어디까지나 공통 이벤트에 공통 이벤트를 호출하면서 생기는 딜레이이기 때문에 범위 표시 공통 이벤트에 다 때려박으면 되는 거겠지만, 간단한 문제가 아니었다.

 

 공통 이벤트를 만드는 목적에는 보기 편하게 구분하는 것도 있지만, 더 중요한 것은 원활한 수정이다. 복붙으로 만들면 수정 사항이 생겼을 때 모두 찾아 뜯어고쳐야 하지만, 공통 이벤트를 호출하게 만든 상태라면 해당 공통 이벤트만 고치면 되기 때문.

 

 안 그래도 이 스킬 타겟 예외 처리는 범위 인식을 위해 불러오는 '기본 공격 타겟 예외처리' 공통 이벤트가 껴있어서 속도가 2배로 느려지는데다가, 여기엔 맵 추가나 변경에 따라 벽을 다르게 감지해줄 조건 분기가 들어가 있어서 그대로 깡복붙을 하는 건 정말 미친짓이었다.

 

벽이나 연출용 이벤트의 수는 매우 적기 때문에 이렇게 맵마다 별도로 처리하게 만들었다.

 

 즉, 맵이 늘어남에 따라서 이 조건 분기가 계속 늘어나야 하는데 이걸 모두 복붙해서 넣으면 맵을 만들 때마다 이 이벤트가 계속 수정되어야 한다는 소리다. 수정하다가 세월 다 간다는 소리다!!!

 

 

 그래서 머리를 싸매고 찾은 방법은 공통 이벤트는 아니되 유동적인 수정이 가능하며 공통 이벤트처럼 호출할 수 있게 하는 것이었다.

 

 

 그렇다. 이 공통 이벤트의 내용을 그냥 스크립트화 해버리면 되는 것이다.

 

 이전에 다른 기능을 테스트하며 알게된 사실이지만, 스크립트로 작성된 내용은 동일한 걸 이벤트로 작성하는 것보다 처리 속도가 월등하게 빠르다. 나는 정석으로 스크립트를 작성하는 재주 같은 건 없지만, 다행히 이벤트로 작성할 수 있는 모든 건 어떻게든 스크립트로 만들 수 있다. (위에 이벤트 중간중간 나온 script도 모두 변수로 자동화하기 위해 이벤트의 내용을 스크립트화 한 것 뿐이다.)

 

 고로 빈 스크립트 창을 만들어서 위의 내용을 코드로 적기만 하면 된다.

 

조잡하지만 위의 공통 이벤트 두개를 처리한 것과 똑같은 내용이다. 무려 하나의 def로 압축도 됐다!

 

그리고 기존의 [적 스킬 타겟 예외처리] 공통 이벤트를
동일한 내용의 스크립트를 호출하도록 바꿨다.

 

 

 그 결과...

 

 

완. 벽.

 

 이렇게 범위의 동시 재생처리도 고쳐지고, 예외처리 타겟도 만들어졌다.

 

 기존에 알만툴에 존재하는 판정에 없는 걸 만드는 건 진짜 맨땅에 헤딩하는 짓이다. 특히나 툴에 대한 지식이 별로 없으면 절대 추천하지 않는다. 나름 알만툴 다루기엔 고인물이 됐다고 생각하는데도 프로그래밍 기반이 없어서인지 아직도 의문 투성이인게 많다. 오늘처럼 공통 이벤트를 공통 이벤트에 부르면 왜 딜레이가 생기는가 같은 거 말이다.

 

 그래도 하다보면 잘 만들어졌을 때 뿌듯함이 커서 의외로 즐겁기도 하다. 왜 굳이 쯔꾸르로 이런 짓을 하냐는 질문도 받았었지만, 이 게임 시리즈의 태생이 쯔꾸르인걸 어쩌겠나 나는 쯔꾸르를 좋아하는 사람들이 좋고, 쯔꾸르로 만든 나의 게임을 좋아해주는 사람이 좋다.

 

 수익은 뭐... 이거 완성하고 싸게 팔면 누군간 사주겠지? 사랑합니다 여러분.

 

관련글 더보기