[Unreal] 25일차 - Enemy Attack State 함수, Move 전환, Damage State 함수, 넉백(Knockback)

2024. 8. 23. 00:56Unreal Engine

728x90
반응형

적 Attack 함수 작성

Idle 상태 함수에서 쓰인 시간이 흐르고 시간이 기준 시간을 넘었을 때 상태를 변화해주는 기능이 똑같다.

해당 기능을 함수로 가져올 것이다.

Idle State 함수에서 노드들을 묶어서 [Collapse to Function]으로 함수로 만들어준다.

 

 

FlowTime으로 이름 붙였다.

 

 

그런데 이 함수에는 IdleDelayTime 외부 변수가 있다. 이 함수를 Attack에도 쓰려면 해당 부분에 AttackDelayTime이라는 다른 변수를 사용해야 한다. 따라서 이 부분을 바꿔줄 수 있도록 해야한다.

 

 

우측 Details에 보면 Inputs가 있다. 여기에 + 버튼을 눌러 input을 하나 추가하고 float 형의 "DelayTime"을 생성했다.

"get delay time" 노드를 해당 자리에 넣었다.

 

 

Outputs에도 "IsFinish?" 이름의 Boolean ouput을 하나 생성해서 맨 뒤 노드에 연결한다. True로 끝났으면 체크를, False로 끝났으면 체크를 하지 않는다.

 

 

IdleState 함수에서 [Branch] 노드를 하나 만들고 IsFinish?가 True일 때 상태를 변경하도록 만든다. Input 자리에 IdleDelayTime을 연결한다. Attack 상태에서는 AttackDelayTime을 연결하면 될 것이다.

 

 

Attack State 함수도 동일하게 설정하였다. 일정 시간이 지나면 Attack!이 출력되도록. Attack Delay Time 변수는 전역 변수로, Idle Delay Time을 복제해서 이름만 수정했다.

 

 

2초에 한 번씩 Attack!이 출력된다. Attack Delay Time의 값이 2.0 이기 때문.

 

 


 

 

타겟이 공격 범위를 벗어나면 이동으로 전환

Attack State에서 Move State로 돌아가는 전환을 만들어야 한다.

Attack State에서 노드를 추가한다. 타겟과 나의 거리의 차이가 Attack Range 변수 값보다 커지면 다시 Move State로 변환한다.

 

 

전체 Attack State 함수 노드

 

 

적에게서 멀어지니까 따라오는 것을 볼 수 있다.

 

 


 

 

Damage State

피격은 대기, 이동, 공격 어떤 상태에서도 당할 수 있다. AnyState.

 

 

BP_Player에 FireSniper 함수를 연다. 물리적으로 날려보내기 전에 데미지를 입히는 노드를 넣을 것이다.

 

 

그 전에 BP_EnemyFSM으로 가서, OnDamageProcess 이름의 함수를 하나 만들었다.

 

 

함수는 간단하게 Me 변수를 가져와서 [Destroy Actor]를 연결했다.

 

 

이제 BP_Player의 EventGraph로 간다.

BP_Enemy의 컴포넌트 중 BP_EnemyFSM에 있는 OnDamageProcess 함수를 호출하고 싶다.

 

 

[Line Trace By Channel] 노드의 Out Hit Hit Actor에서 시작한다.

[Get Component by Class] 노드에서 BP_EnemyFSM을 가지고 있는지 [Is Valid]를 이용해서 판단한 후 유효하면 [On Damage Process]를, 아니라면 큐브를 날려보냈던 것처럼 이후 물리적 충돌을 이어나가면 된다.

 

 


 

 

BP_Enemy 충돌처리

아직 총으로 쏴도 적을 맞추지는 못한다. 충돌처리가 되어있지 않기 때문.

BP_Enemy의 Capsul Component의 Collider 중 Visibility를 Block으로 설정해야 한다.

 

 

그 이유는 [Line Trace By Channel] 노드가 Visibility를 가져오기 때문.

 

 

이제 적을 맞추면 없어진다.

 

 


 

 

Damage State 계속

Enemy에게 HP를 부여한다.

BP_EnemyFSM에서 HP 이름의 Integer 변수 추가, 디폴트 값은 3을 부여했다.

 

 

OnDamageProcess 함수로 들어간다.

HP 변수를 --로 하나씩 빼고 0보다 아직 크면 Damage 상태, 0보다 작으면 Die 상태로 설정했다.

 

 

이 상태에서 실행해서 쏘면 Idle -> Damage -> Die로 바뀌는 것을 볼 수 있다. (BP_EnemyFSM에 [Print String]을 연결했을 때)

 

 


 

 

Damage 상태일 때 일정 시간 후 Idle로 전환

피격 후 대기시간이 필요하기 때문에 BP_EnemyFSM에서 AttackDelayTime을 복제하여 DamageDelayTime을 만들었다.

 

 

Damage State 함수로 들어간다.

이전 State에서 시간이 흐르는 함수를 만들었다. [Flow Time] 함수를 끌어놓고 DamageDelayTime 변수를 연결한다. 

 

 

그런데 이렇게 되면 적이 나를 공격하는 중에 적에 피격당하면 Current Time이 꼬여서 제대로 작동하지 않는다.

OnDamageProcess에 진입하면 Current Time을 초기화 시켜주어야 한다.

 

 


 

 

넉백

여기서 적이 넉백을 당하게 하려면 OnDamageProcess에 Inputs를 추가한다.

 

 

그리고 함수의 시작 부분에 Hit Direction을 벡터로 하고 Kockback Power를 크기로 하는, P = P0 + v*t의 공식을 이용하여 움직임을 뒤로 줄 것이다.

KnockbackPower의 디폴트 값은 5000이다.

 

 

BP_Player로 돌아와서, OnDamageProcess에 Camera의 [Get Forward Vector] 값을 Hit Direction에 연결하면 된다.

 

 

정리 차원에서, 현재 BP_Player의 전체 EventGraph

 

 

쏠 때마다 뒤로 밀리는 것을 볼 수 있다.

 

 


 

 

OnDamageProcess의 넉백 부분을 Damage State로 옮긴다. Knockback으로 감싼 코멘트 부분을 통으로 옮길 건데, HitDirection은 현재 지역변수이기 때문에 전역변수로 변환하기 위해서 [Promote to Variable] 한다.

 

 

HitDirection 변수를 아래와 같이 배치한다.

 

 

Knockback 코멘트 묶음은 잘라내기 해서 Damage State에 붙여넣고, 남은 노드를 연결한다.

 

 

Damage State로 가서 잘라온 부분을 연결한다.

이대로 실행하면 2초 동안 밀려난다.

728x90
반응형