-
240426~240503 파트너 캐릭터 위치를 나타내는 UI (3)기록 2024. 5. 4. 16:33
목표 : 다른 캐릭터(파트너)위치를 나타내는 UI를 만들기
- 위젯 만들기 (완료)
- 플레이어에 위젯 컴포넌트로 붙이기 (완료)
- 거리에 따라 위젯 on/off기능 (완료)
- 화면 랜더링 여부에 따라 on/off기능 + 랜더링이 되지 않을 때 화면에서 방향을 가르키도록 하기(완료!)
4. 화면 랜더링 여부에 따라 on/off기능 + 랜더링이 되지 않을 때 화면에서 방향을 가르키도록 하기
고민됐던 점
1. 화면 랜더링 여부 확인하기(완료)
2. 랜더링 되지 않았을 때 화면에 어떻게 표현할 것인지.(진행)
이전에 진행상황을 확인해보면
240426~240503 파트너 캐릭터 위치를 나타내는 UI (2)
목표 : 다른 캐릭터(파트너)위치를 나타내는 UI를 만들기 위젯 만들기 (완료)플레이어에 위젯 컴포넌트로 붙이기 (완료)거리에 따라 위젯 on/off기능 (완료)화면 랜더링 여부에 따라 on/off기능 +
hayo-su.tistory.com
변경 전)
- 본인의 위젯 컴포넌트는 본인이 볼 수 없게 설정해 두었고,
- 위젯 컴포넌트에서 본인이 아닌 플레이어를 찾고, 이 플레이어에서 (본인)위젯의 랜더링 여부를 확인하였다.
변경 후)
1. 위치에 따라 랜더링 여부를 확인할 것
2. 뷰포트 내에 존재 여부에 따라 위치를 조정할 것
다음을 만족하게 만들기 위해서 반대로 본인의 위젯 ->파트너 위치 나타내기가 더 쉬울 것이라고 생각하였다.(2인 플레이 게임이라 가능한 부분이다.)
진행
// Set widget classes if (PlayerMarkerWidget) { PlayerMarkerWidget->SetWidgetClass(PlayerMarkerType); } // Set widget space to screen PlayerMarkerWidget->SetWidgetSpace(EWidgetSpace::Screen); // Check if the owner of the widget component is the same as the player controller if(Cast<APawn>(GetOwner()) == GetWorld()->GetFirstPlayerController()->GetPawn()) { // 본인인 경우 랜더링 SetVisibility(true, true); } else { //타인인 경우 랜더링하지 않음 SetVisibility(false, true); }
1. 본인이 아닌 위젯은 visible false설정을 하였다.
// .h // 위젯을 통해 위치를 표시할 타겟 플레이어 정보 APlayerBase* TargetPlayer;
// .cpp void UPlayerMarkerUI::FindTarget() { TArray<AActor*> AllPlayerActors; UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerBase::StaticClass(), AllPlayerActors); APlayerBase* me = Cast<APlayerBase>(GetOwner()); // PlayerActors를 순회하며 각 플레이어의 처리 수행 for (AActor* Player : AllPlayerActors) { if (me != Cast<APlayerBase>(Player)) { TargetPlayer = Cast<APlayerBase>(Player); return; } // Player를 사용하여 플레이어 처리 } } void UPlayerMarkerUI::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { if (TargetPlayer == nullptr) { FindTarget(); return; } }
2. 타겟 플레이어가 설정되지 않는경우 본인이 아닌 다른 플레이어가 target에 설정될 수 있도록 설정
APlayerController* FirstPlayer = GetWorld()->GetFirstPlayerController(); FVector2D ActorScreenPosition; // 타겟 플레이어의 스크린 포지션 위치를 연산 if (!FirstPlayer->ProjectWorldLocationToScreen(TargetPlayer->GetActorLocation(), ActorScreenPosition)) { return; // Failed to project actor's location to screen space } int32 ViewportX, ViewportY; // 뷰포트 가져오기 FirstPlayer->GetViewportSize(ViewportX, ViewportY); // 화면에 랜더링 되는 경우 if ((ActorScreenPosition.X >= 0 && ActorScreenPosition.X <= ViewportX && ActorScreenPosition.Y >= 0 && ActorScreenPosition.Y <= ViewportY)) { } else // 화면에 랜더링이 되지 않는경우 { }
3. 타겟플레이어의 랜더링 여부를 확인함.
float Distance = FVector::Distance(FirstPlayer->GetPawn()->GetActorLocation(), TargetPlayer->GetActorLocation()); if (DistanceThreshold < Distance) { SetVisibility(true, true); } else { SetVisibility(false, true); } SetWorldLocation(TargetPlayer->GetActorLocation()+ WidgetDefaultLocation);
4. 화면에 존재하는 경우 거리에 따라 랜더링 여부를 결정하고, 타겟 플레이어 위치로 위젯 위치를 설정함.
SetVisibility(true, true); if (ActorScreenPosition.X < 0) { ActorScreenPosition.X = 10.0f; } else if (ActorScreenPosition.X > ViewportX) { ActorScreenPosition.X = ViewportX - 10.0f; } if (ActorScreenPosition.Y < 0) { ActorScreenPosition.Y = 10.0f; } else if (ActorScreenPosition.Y > ViewportY) { ActorScreenPosition.Y = ViewportY - 10.0f; }
5. 화면 밖에 존재하는 경우 랜더링하도록 설정하고 액터의 스크린 포지션을 화면 내 위치로 보정한다.
FVector WorldLocation, WorldDirection; FirstPlayer->DeprojectScreenPositionToWorld(ActorScreenPosition.X, ActorScreenPosition.Y, WorldLocation, WorldDirection); // 카메라 스페이스 좌표로 변환한 후, 카메라와 WidgetComponent의 거리 계산 FVector CameraLocation = FirstPlayer->PlayerCameraManager->GetCameraLocation(); FVector WidgetLocation = CameraLocation + WorldDirection * 1200.0f; // 예시로 거리를 100.0f로 설정 SetWorldLocation(WidgetLocation + WidgetDefaultLocation);
6. 보정한 스크린좌표계 값을 바탕으로 월드 좌표계값을 가져온 후 , 카메라의 스프링암이 1200.0f길이를 가지고 있기 때문에 해당 정보를 반영
추가 변경 예정 ) 화면 밖에 존재하는 경우 위젯의 회전이 적용될 수 있도록 변경 예정이다.
플레이어의 카메라, 뷰포트, 프로젝션 등 3D공간에서 2D공간으로 랜더링 되는 순서와 반대로 2D에서 3D공간에 적용하는 방법에 대해 오랫동안 고민해 보았다.
'기록' 카테고리의 다른 글
240426~240503 리스폰UI (0) 2024.05.04 240426~240503 플레이어 HP UI 디테일 추가 (0) 2024.05.04 240426~240503 파트너 캐릭터 위치를 나타내는 UI (2) (0) 2024.05.04 240426~240503 파트너 캐릭터 위치를 나타내는 UI (1) (0) 2024.05.04 240418 플레이어 RPC를 사용하여 사이즈 변경 동기화 (0) 2024.04.21