일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- DP
- Brute Force
- union find
- two pointer
- Hash
- Two Points
- SQL
- Dijkstra
- 스토어드 프로시저
- 다익스트라
- Stored Procedure
- MYSQL
- Trie
- String
- 그래프
- 이진탐색
- binary search
- Today
- Total
codingfarm
펀치 - 충돌 이벤트(Hit Event) 본문
각 액터가 서로 충돌이 발생했을때에 이벤트가 발생하는 방법에 대해 알아보겠다.
앞서 우리는 클릭과 함께 주먹을 휘두르고 박스가 이에 반응하도록 프로젝트를 구성했으며 여기서부터 이어나가겠다.
먼저 주먹이 충돌했을때 호출될 아래와같은 이벤트 함수의 원형을 헤더파일에 넣는다.
1
2
|
UFUNCTION()
void OnAttackHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
|
cs |
이벤트가 될 함수는 반드시 UFUNCTION() 데코를 설정해주어야한다.
함수 정의는 아래와 같으며 지금은 충돌 감지가 잘 되는지 확인하는 용도로 로그만 출력한다.
1
2
3
4
|
void APunchKick04Character::OnAttackHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
Log(ELogLevel::WARNING, __FUNCTION__);
Log(ELogLevel::WARNING, Hit.GetActor()->GetName());
}
|
cs |
이 함수를 Collision Box가 충돌시에 호출되도록 아래 코드의 10, 11번째 줄에서 OnAttackHit 함수를 이벤트로 등록 한다.
1
2
3
4
5
6
7
8
9
10
11
12
|
void APunchKick04Character::BeginPlay() {
Super::BeginPlay();
// attach collision components to sockets based on transformations definitions
const FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, false);
LeftFistCollisionBox->AttachToComponent(GetMesh(), AttachmentRules, "fist_l_collision");
RightFistCollisionBox->AttachToComponent(GetMesh(), AttachmentRules, "fist_r_collision");
LeftFistCollisionBox->OnComponentHit.AddDynamic(this, &APunchKick04Character::OnAttackHit);
RightFistCollisionBox->OnComponentHit.AddDynamic(this, &APunchKick04Character::OnAttackHit);
}
|
cs |
그리고 충돌시 이벤트가 발생되기 위해선 Collider Component에서 simulation genarates hit events가 true로 설정하여 충돌감지를 진행해야한다.
(오버랩 이벤트 발생을 위해선 Generate Overlap Events를 true로 설정해주면된다.)
하지만 모든 시간에 계속해서 감지를 진행하는 것은 리소스의 낭비가 심하므로 실제 공격이 실행 될때만 감지되게 한다.
그러기 위해서는 AttackStart() 함수의 호출과 함께 true로 설정하고, AttackEnd() 함수의 호출과 함께 false로 설정한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
void APunchKick04Character::AttackStart()
{
Log(ELogLevel::INFO, __FUNCTION__);
LeftFistCollisionBox->SetCollisionProfileName("Weapon");
LeftFistCollisionBox->SetNotifyRigidBodyCollision(true);
RightFistCollisionBox->SetCollisionProfileName("Weapon");
RightFistCollisionBox->SetNotifyRigidBodyCollision(true);
}
void APunchKick04Character::AttackEnd()
{
Log(ELogLevel::INFO, __FUNCTION__);
LeftFistCollisionBox->SetCollisionProfileName("NoCollision");
LeftFistCollisionBox->SetNotifyRigidBodyCollision(false);
RightFistCollisionBox->SetCollisionProfileName("NoCollision");
RightFistCollisionBox->SetNotifyRigidBodyCollision(false);
}
|
cs |
그리고 런타임시 버그를 방지하기 위해 생성자 내에서도 false로 설정하는 코드를 추가하도록 한다.
OnAttackHit 함수에서 매개변수 Hit를 통해 충돌한 오브젝트에 대한 정보를 얻을 수 있다.
1
2
3
4
|
void APunchKick04Character::OnAttackHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
Log(ELogLevel::WARNING, __FUNCTION__);
Log(ELogLevel::WARNING, Hit.GetActor()->GetName());
}
|
cs |
좌측위에 노란색 노드로 캐릭터가 타격했다는 문자열과 타격당한 액터의 이름이 출력됨을 확인 할 수 있다.
한가지 주목할점은 주먹과 enemy가 서로 충돌하는 순간에는 애니메이션이 재생을 끝까지 하지 않고 도중에 멈춘다는점이다.
'Unreal 4 > 기타' 카테고리의 다른 글
펀치 - 발차기 (0) | 2020.07.22 |
---|---|
펀치 - 소리 재생 (0) | 2020.07.20 |
펀치 - 스켈레톤 소켓 (0) | 2020.07.19 |
펀치 - 애니메이션 몽타주 (0) | 2020.07.18 |
애님 에셋 리타게팅 (0) | 2020.07.18 |