RPG 창작일지 - 오토 캐스팅 스킬 제작

https://arca.live/b/unreal/101661553?category=%EB%B8%94%EB%A3%A8%ED%94%84%EB%A6%B0%ED%8A%B8%EC%98%88%EC%A0%9C&p=1

위 글에서 이어집니다.



 실험이 모두 마무리되고 기쁜 마음에 구현을 시작하려고 했으나, 뭔가 놓치고 있음을 느꼈음.

알아낸 시스템 구조가 맞다면 스킬이 오토 캐스팅이 되지만 블러드러스트와 다른 스킬, 즉, 


 네크로멘서의 레이즈 데드 같은 경우에 문제가 생겼음.

블러드러스트는 공격 중인 주변 아군에게 자동으로 사용됨.

레이즈 데드는 주변 시체가 있을 때 자동으로 사용함.

행동 정보가 전송됐을 때 시스템이 이벤트를 구독한 샤먼 중 하나한테 스킬을 쓰게 하는 구조라면

행동 정보는 전송됐을 때만 사용되고 이후 버려져야 맞음.


 만약 '유닛 사망'을 행동 정보로 넘겨준다면, 이벤트를 구독한 네크로멘서만 레이즈 데드를 쓸 것임.

다들 알겠지만 시체가 생성된 뒤에 레이즈 데드를 오토 캐스팅으로 설정해도 잘 사용됨.

범위 밖에서 생성된 시체도 동일함.


 행동 정보가 일회용으로 사용된다면

유닛이 행동 중이든 아니든 체력이 깎인 주변 유닛에게 자동으로 사용 프리스트의 힐도,

디버프가 걸려 있는 아군 또는 버프가 걸려 있는 적을 발견하면 쓰는 드라이어드의 어볼리쉬 매직도 성립할 수 없음.



 요약하면 

블러드러스트처럼 필요한 행동 정보가 그 순간에만 사용되는 일회용이어도 문제 없지만 

일부 스킬은 해결될 때까지 계속 유지돼야 하는 행동 정보가 필요하다는 것임.


 각 스킬에 맞는 이벤트를 만들면 된다고 생각하면 합리적이지 않음. 

일단 하드코딩을 해야 되니까 안 되고, 힐의 파생 스킬이 작동하지 않아서 안 됨.

이쯤에서 블러드러스트가 필요한 행동 정보는 일회용은 맞는지 의심이 들었음.



실험 1. 오토 캐스팅 상태의 블러드러스트는 공격 중이지만 공격 효과가 없을 때 유닛에게 블러드러스트를 사용할까?


(헤헌은 공속, 발사체 속도 모두 최하로 설정됐음. 그래서 영상에는 공격을 했음에도 불구하고 발사체가 적중하지 않았음)


아니었음... 역시 한 번만 실험해서 결론에 도달하면 안 됨...

행동 정보는 사용될 때까지 저장되는 셈임. 

그러므로 행동 정보가 전송될 때마다 이벤트가 호출될 수도 있으나, 

스킬이 자신이 사용 가능한 상태일 때도(쿨 돌았거나, 마나가 찼거나) 이벤트가 호출돼야 함.

이래도 모든 행동 정보가 사용되지 못할 수도 있으니 주기적으로 호출돼야 함.


가설1

모든 유닛은 자신이 특정 상황을 겪었을 때 자신이 겪은 상황을 정보로 가공해서 시스템에 넘김.

모든 오토 캐스팅 스킬은 자신이 사용되는 조건과 동일한 상황에만 호출되는 이벤트를 구독함.

이벤트에 구독했지만 사용 불가능하게 된 경우(마나가 빠졌거나, 쿨다운이 있거나, 사일런스를 맞았거나) 구독을 해제해야 함.

이벤트는 추가 구독이 있거나, 상황 정보가 전송되거나, 일정 시간마다 호출돼야 함.

enum 상황 ID 

{ //상황들... }

TMap<상황ID, 유닛*> 유닛들;

TMap<상황ID, 델리게이트> 이벤트;


void Broadcast(상황ID _ID)

{

    if (유닛들.Contains(_ID) && 이벤트.Contains(_ID))

    {

        //반복문 돌려서 호출

    }

}


힐과 블러드러스트도 그런 면이 있지만 드라이어드의 어볼리쉬 매직은 자신의 팀이 아닌 아군이나 적에게도 사용되므로 

위의 두 인스턴스는 모든 유닛이 공용 공간에 선언돼야 함.

특정 팀한테만 사용 가능한 스킬을 위해 특수 공간을 마련하면 안 됨. 

그러면 구독을 여러 번 해야 하고, 팀이 바뀌었을 때 수정할 게 늘어나며, 업그레이드 같은 이유로 조건이 바뀌었을 때 복잡해짐

워크래프트3의 트리거 에디터도 이런 느낌이던데... 서로 같을 수도..



실험 2. 모든 스킬이 공용 공간에 존재하는 이벤트를 구독할까?


(모든 드라이어드는 어볼리쉬 매직만 쓰도록 설정됐고 어볼리쉬 매직의 쿨다운은 0임. 파랑, 연초, 보라는 모두 동맹임.)


드라이어드는 파랑, 연초, 보라 순으로 유닛이 생성됐음.

위 영상에서 네 가지를 확인할 수 있었음.


1. 모두가 공용 공간에 있는 이벤트를 구독함

2. 범위 안에 있는 스킬을 호출하지만 가장 가까울 필요는 없음.

--> 연초 드라이어드가 있음에도 불구하고 파랑 드라이어드가 어볼리쉬 매직을 씀.


3. 유닛이 스킬을 사용하면 이벤트 구독을 해제하고 스킬 모션이 끝날 때까지 다시 구독함.

--> 쿨다운을 0으로 설정했는데 한 마리의 드라이어드가 계속 쓰지 않고 돌아가면서 스킬을 씀.


4. 일정 시간마다 이벤트를 호출함.

--> 블러드러스트가 사라졌을 때 샤먼이 즉각 버프를 주지 않았음.


 그리고 '공격 중'과 같은 상황 정보는 그 상황이 끝날 때까지 공용 공간에 저장되는 듯함.

(공격 중의 경우 대상이나 본인이 죽었거나, 다른 명령을 수행하는 등으로 끝났을 때)

아마도 그 상황에서 벗어난 유닛이 본인이 그 상황에서 벗어났다고 알림을 주겠지?



결론

모든 유닛은 자신이 특정 상황을 겪었을 때 자신이 겪은 상황을 정보로 가공해서 시스템에 넘김.

모든 오토 캐스팅 스킬은 자신이 사용되는 조건과 동일한 상황에만 호출되는 이벤트를 구독함.

이벤트에 구독했지만 사용 불가능하게 된 경우 구독을 해제함.

이벤트는 추가 구독이 있거나, 상황 정보가 전송되거나, 일정 시간마다 호출됨.

enum 상황 ID 

{ //상황들... }

TMap<상황ID, 유닛*> 유닛들;

TMap<상황ID, 델리게이트> 이벤트;
















번외 실험 1. 마나 플레어는 뭐에 반응할까?


상황 정보는 여러 개의 ID를 갖는 듯함. 위 영상의 경우에는

힐:                상황ID(스킬을 씀), 스킬타입(이건 버프임), 유닛 정보(이건 아군이 안 썼음)

아군 슬로우:   상황ID(스킬을 씀), 스킬타입(이건 디버프임), 유닛 정보(이건 아군이 안 썼음)

적 슬로우:      상황ID(스킬을 씀), 스킬타입(이건 디버프임), 유닛 정보(이건 아군이 썼음)


아군 언홀리 프렌지: 상황ID(스킬을 씀), 스킬타입(??), 유닛 정보(이건 아군이 썼음)


처럼 분류되는 듯. 만약 타입분류가 없다면 마나 플레어는 버프와 디버프 이벤트를 둘 다 구독해야 할 것임.

아니 여러 상황ID(디버프 씀, 디버프 맞았음)이 존재하고 둘 다 구독하는 편이 맞을 듯. 

그렇지 않으면 영상처럼 양팀 소서리스들이 일제히 자기팀을 때린 놈에게 슬로우를 쓸 리가 없음.

언홀리 프렌지는 정확히 뭐인지 모르겠음. 만약 디버프라면 소서리스가 슬로우로 보복했을 것임.



번외 실험 2. 언홀리 프렌지는 정확히 뭘까?


스펠 브레이커는 슬로우를 배구공 다루듯 열심히 넘기지만 

언홀리 프렌지는 눈물이 날 정도로 관심을 주지 않음..


이렇게 어떤 스킬은 버프 취급도, 디버프 취급도 아닐 수 있다는 사실을 알았음..

둘 중 하나라도 해당되면 넘기거나 가져오겠지 저렇게 이 악물고 무시하지 않음...

스킬 분류용 열거형이 있다면 반드시 None이 있을 것임.