마커는 여러개가 동시에 뜰 수 있고 개수가 런타임에 계속 바뀌는데, 그 생명주기 관리와 매 틱 화면 계산을 한 곳에서 하기 위한 관리자 레이어
생성/제거 동기화 : NSWaypointSubsystem의 OnWaypointLIstChanged 델리게이트를 구독해서, 마커 컴포넌트가 등록/해제될 때마다 마커 위젯을 만들거나 지움(RegreshMarkerWidgets), 마커 위젯 개별로는 자기가 언제 생기고 사라져야 하는지 알 수 없음
매 틱 공통 계산 : 월드 좌표 -> 스크린 투영, 카메라 뒤 판정, 화면 밖일때 가장자리 클램프, 거리 텍스트/스케일 갱신을 컨테이너의 NativeTick 한곳에서 전부 처리. 뷰포트 크기, DPI, 카메라 시점 같은 공통 값을 한 번만 구해서 모든 마커에 재사용할 수 있고, 마커 위젯 각각이 틱을 도는 것보다 효율적
배치 공간 제공 : 아이콘 + 거리 텍스트 비주얼만 담당하고,
인런 실행하면 두가지가 발생함
그냥 구출 목표 id반환하는 함수
// 캐릭터 선택 콘솔과 첫 상호작용 (NSCharacterSelectNPC::OnInteract에서 호출)
void NotifyCharacterConsoleUsed();
// 게임시작 콘솔과 첫 상호작용 (NSReadyStartActor::OnInteract에서 호출)
void NotifyReadyConsoleUsed();
// 허브 NPC와 첫 상호작용 (NSPlayerController::OpenInteractionWidget에서 호출)
void NotifyNPCInteracted(FName NPCId);
우선 틱 에서 MarkerWidget은 많은 효과가 있다.
1단계 화면 투영 (마커가 화면에 있을때) -> ProjectWorldLocationToScreen이 카메라 투명 행렬을 이용해서 월드 좌표 -> 스크린 픽셀 좌표로 변환해줌, 대상이 카메라 시야 안(정확히는 투명 평만 앞)에 있으면 성공(true)하고 픽셀 좌표를 채워줌
2단계 화면 안인지 판정(카메라 뒤 케이스가 핵심), ProjectWorldLocationToScreen은 대상이 카메라 뒤에 있으면 false를 반환하긴 하는데 그 전에 이미 계산된 스크리 좌표값이 남아있어서 신뢰할 수 없다. 그래서 내적(DotProduct)으로 직접 한번 더 확인함
WorldLocation -> CameraLocation(카메라->대상 액터) 과 CameraForward(카메라가 보는 방향)의 내적이 음수면 대상이 카메라보다 뒤에 있다는 뜻
투영 성공 + 카메라 앞 + 여백(EdgePadding) 안쪽까지 다 만족해야 '화면 안'으로 인정합니다. 여백을 두는 이유는 마커가 화면 가장자리에 딱 붙어서 잘려 보이지 않게 하기 위해서입니다.
3단계 가장자리 글램핑 (화면 밖일때 방향만 표시) -