Overlap Events

Jihyun·2023년 12월 22일
0

Unreal

목록 보기
10/11

트리거 박스를 C++ 컴포넌트로 만들기

어떤 컴포넌트나 액터가 Trigger Component와 오버랩 되고 있는지 확인

TArray

TArray를 사용해 액터 목록을 가져오고, 목록 내 액터의 개수를 확인한다.

오버랩되는 액터의 이름 가져오기

목록 내에서 첫 번째 액터에 접근하여 액터의 이름을 출력한다.

void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    if(Actors.Num() > 0)
    {
        FString ActorName = Actors[0]->GetActorNameOrLabel();
        UE_LOG(LogTemp, Display, TEXT("Overlapping: %s"), *ActorName);
    }

}

오버랩되는 모든 액터의 이름 가져오기

반복문을 사용하여 Actors 배열에 저장되는 모든 액터의 이름을 가져온다

  • while문 사용
void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    int32 index = 0;
    while(index < Actors.Num())
    {
        FString ActorName = Actors[index]->GetActorNameOrLabel();
        UE_LOG(LogTemp, Display, TEXT("Overlapping: %s"), *ActorName);
        ++index;
    }   


}
  • for문
void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    for(int32 i =0; i < Actors.Num(); i++)
    {
        FString ActorName = Actors[i]->GetActorNameOrLabel();
        UE_LOG(LogTemp, Display, TEXT("Overlapping: %s"), *ActorName);       
    }  
}
  • 범위 기반 for문
void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    //TArray의 모든 액터를 순회
    for(AActor* Actor : Actors)
    {
        //인덱스를 사용해 직접 배열에 접근하는 대신 액터 포인터 변수 사용
        FString ActorName = Actor->GetActorNameOrLabel();
        UE_LOG(LogTemp, Display, TEXT("Overlapping: %s"), *ActorName);     
    }  

}

Actor Tags

액터에 태그를 추가하여 해당 액터로만 오버랩 이벤트 작동시키기

  • Actor Tag : 액터에 문자열 태그를 달아 특정 액터만을 구분할 수 있다
UPROPERTY(EditAnywhere)
FName AcceptableActorTag;

void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    //TArray의 모든 액터를 순회
    for(AActor* Actor : Actors)
    {
        
        if(Actor->ActorHasTag(AcceptableActorTag))
        {
            UE_LOG(LogTemp, Display, TEXT("Unlocking")); 
        }
          
    }  

}

트리거 컴포넌트 안에 특정 오브젝트가 있는지 확인하기

void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    AActor* Actor = GetAcceptableActor();
    if(Actor != nullptr)
    {
        UE_LOG(LogTemp, Display, TEXT("Unlocking"));
    }
    else
    {
        UE_LOG(LogTemp, Display, TEXT("Relocking"));
    }

}

AActor* UTriggerComponent::GetAcceptableActor() const
{
    TArray<AActor*> Actors;
    GetOverlappingActors(Actors);

    //오버랩 된 액터 목록의 모든 액터를 순회
    for(AActor* Actor : Actors)
    {
        //액터가 해당 태그(AcceptableActorTag)를 가지고 있는지 확인        
        if(Actor->ActorHasTag(AcceptableActorTag))
        {
           return Actor;           
        }          
    }

    return nullptr;

}

캐스팅과 액터 부착

void UTriggerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    AActor* Actor = GetAcceptableActor();
    if(Actor != nullptr)
    {
        //USceneComponent가 UPrimitiveComponent인지 확인
        //Actor의 루트 컴포넌트를 가져와 UPrimitiveComponent인지 확인
        UPrimitiveComponent* Component = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
        if(Component != nullptr)
        {
            //물리 시뮬레이터 비활성화
            Component->SetSimulatePhysics(false);

        }
        UE_LOG(LogTemp, Display, TEXT("Unlocking"));

        //액터를 컴포넌트에 부착한다
        Actor->AttachToComponent(this, FAttachmentTransformRules::KeepWorldTransform);

        //Mover 포인터에 접근하여 SetShouldMove 호출
        Mover->SetShouldMove(true);        
    }
    else
    {
        UE_LOG(LogTemp, Display, TEXT("Relocking"));
        Mover->SetShouldMove(false);
    }

}

AActor::GetRootComponent() : 액터의 루트 컴포넌트 반환

UPrimitivieComponent::SetSimulatePhysics() : false를 반환 받으면 물리 시뮬레이션을 비활성화 할 수 있다

AActor::AttachToComponent : 액터의 루트 컴포넌트를 다른 컴포넌트에 부착한다

profile
잊어버려도 다시 리마인드 할 수 있도록 공부한 것을 기록합니다

0개의 댓글