물리 오브젝트 꺠우기
물리 시물레이션 컴포넌트는 성능상의 이유로 일정 시간 동안 가동되지 않으면 슬립 상태로 들어간다.
따라서 구체 트레이스로 히트했을 때 깨어나도록 만드는 방법을 알아야 합니다
UPrimitiveComponent
컴포넌트 클래스 중 하나입니다. 이 클래스는 게임 내에서 물리적인 상호작용과 시각적 표현을 모두 다룰 수 있는 기본적인 구성 요소입니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/Components/PrimitiveComponent.h |
Include | #include "Components/PrimitiveComponent.h" |
Syntax
class UPrimitiveComponent :
public USceneComponent,
public INavRelevantInterface,
public IInterface_AsyncCompilation,
public IPhysicsComponent
주요 특징
- 시각적 요소: UPrimitiveComponent는 게임 세계 내에서 시각적으로 렌더링될 수 있는 모든 요소의 기반입니다. 예를 들어, 3D 모델, 라이트, 카메라와 같은 시각적 객체들이 이 클래스를 기반으로 합니다.
- 충돌 처리: 이 컴포넌트는 충돌 검출 및 처리 기능을 제공합니다. 개발자는 이를 통해 객체 간의 충돌을 감지하고, 해당 충돌에 대한 반응을 정의할 수 있습니다.
- 물리 시뮬레이션: UPrimitiveComponent는 물리 시뮬레이션을 지원합니다. 이를 통해 객체가 중력, 힘, 충돌 등 물리 법칙에 따라 동작하게 할 수 있습니다.
- 변환(Transformation): 위치, 회전, 크기 등의 변환을 지원합니다. 이를 통해 개발자는 게임 내에서 객체의 위치, 방향, 크기를 제어할 수 있습니다.
파생 클래스
- UStaticMeshComponent: 정적인 3D 메시(모델)을 표현하는 데 사용됩니다.
- USkeletalMeshComponent: 복잡한 애니메이션을 가진 캐릭터나 동적인 오브젝트를 표현하는 데 사용됩니다.
- UParticleSystemComponent: 파티클 시스템을 사용하여 특수 효과(예: 화재, 연기, 빛)를 구현하는 데 사용됩니다.
- UCameraComponent: 게임 카메라를 표현하는 데 사용됩니다.
사용 사례
- 정적 오브젝트 표현: 건물, 가구 등 게임 환경 내의 고정된 오브젝트들은 UStaticMeshComponent를 사용하여 표현됩니다.
- 동적 캐릭터 및 애니메이션: 게임 캐릭터나 동물과 같이 애니메이션이 필요한 오브젝트들은 USkeletalMeshComponent를 사용합니다.
- 특수 효과: 폭발, 연기, 불꽃 등의 시각적 효과는 UParticleSystemComponent로 구현됩니다.
주의사항
- UPrimitiveComponent는 추상 클래스로서, 직접 인스턴스를 생성할 수 없으며, 구체적인 기능을 제공하는 파생 클래스를 사용해야 합니다.
- 충돌 및 물리 설정은 성능에 영향을 줄 수 있으므로, 필요한 경우에만 적절하게 활성화하고 구성하는 것이 중요합니다.
- 개발 과정에서 이 컴포넌트의 다양한 속성을 조정하여, 원하는 물리적 및 시각적 효과를 얻을 수 있습니다.
UPrimitiveComponent::WakeAllRigidBodies
UPrimitiveComponent 클래스에 속한 함수로, 해당 컴포넌트와 연관된 모든 강체(rigid body) 물리 시뮬레이션을 활성화(깨우는)하는 데 사용됩니다. 이 메서드는 특히 물리적으로 상호작용하는 오브젝트가 "잠든(sleeping)" 상태일 때 유용합니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/Components/PrimitiveComponent.h |
Include | #include "Components/PrimitiveComponent.h" |
Source | /Engine/Source/Runtime/Engine/Private/PrimitiveComponentPhysics.cpp |
Syntax : virtual void WakeAllRigidBodies()
기능 및 사용:
- 강체 물리 시뮬레이션 활성화:
- WakeAllRigidBodies는 컴포넌트에 연결된 모든 강체가 물리 시뮬레이션에 다시 참여하도록 합니다. 이는 오브젝트가 더 이상 움직이지 않아 물리 엔진에 의해 자동으로 "잠든" 상태일 때 주로 사용됩니다.
- 성능 최적화:
- 물리 시뮬레이션은 계산 비용이 높기 때문에, 오브젝트가 활동하지 않을 때 자동으로 "잠자는" 기능이 유용합니다. 이를 통해 불필요한 물리 계산을 줄이고 게임의 성능을 최적화할 수 있습니다.
- 게임 로직에 따른 활성화:
- 게임 내 특정 이벤트나 상호작용에 따라 "잠든" 오브젝트를 깨워 활동하게 만들 수 있습니다. 예를 들어, 플레이어가 특정 지역에 진입했을 때 잠들어 있던 오브젝트를 움직이게 할 수 있습니다.
주의사항:
- WakeAllRigidBodies 메서드는 물리 시뮬레이션을 활성화하므로, 해당 컴포넌트가 물리 시뮬레이션을 지원해야 합니다.
- 물리 시뮬레이션의 활성화는 성능에 영향을 미칠 수 있으므로, 필요한 경우에만 사용하는 것이 좋습니다.
- 이 메서드는 특히 다이내믹 오브젝트에 유용하며, 스태틱 오브젝트(static objects)에는 적용되지 않습니다.
UPhysicsHandleComponent::ReleaseComponent
UPhysicsHandleComponent 클래스의 메서드로, 물리적으로 잡고(manipulate) 있는 컴포넌트를 놓아주는(해제하는) 기능을 제공합니다. 이 메서드는 플레이어가 오브젝트를 들어 올렸다가 놓아야 할 때 주로 사용됩니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/PhysicsEngine/PhysicsHandleComponent.h |
Include | #include "PhysicsEngine/PhysicsHandleComponent.h" |
Source | /Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsHandleComponent.cpp |
Syntax : virtual void ReleaseComponent()
기능 및 사용:
- 잡고 있는 오브젝트 해제
- ReleaseComponent 메서드는 UPhysicsHandleComponent가 현재 잡고 있는 오브젝트의 물리적 연결을 해제합니다. 이는 예를 들어, 플레이어가 오브젝트를 들어 올려 이동한 후, 그 오브젝트를 다시 내려놓을 때 사용됩니다.
- 물리 시뮬레이션 재개
- 오브젝트를 놓을 때, ReleaseComponent는 해당 오브젝트가 다시 자연스러운 물리적 상태로 돌아갈 수 있도록 합니다. 예를 들어, 오브젝트가 지면에 닿으면 중력의 영향을 받아 자연스럽게 떨어지게 됩니다.
●컴포넌트를 집은 후 일정 시간 동안 움직이지 않으면 슬립이 되어 놓아도 아무일이 발생할지 않을 수 있으므로 잡고 있는 컴포넌트를 다시 깨워주는 구문을 추가하였다.
PhysicsHandle->GetGrabbedComponent()->WakeAllRigidBodies();
PhysicsHandle->ReleaseComponent();
●가고일과 Pawn의 충돌 문제
가고일의 Collision에서 커스텀 콜리전 프리셋의 Pawn을 overlap으로 설정하여 무시로 변경(자식 Collision은 부모에 종속됨)
오버랩 이벤트
https://www.unrealengine.com/en-US/blog/collision-filtering
UE5의 각 객체는 least blocking interaction을 취합니다.
충돌 쿼리를 수행할 때 충돌하려는 지오메트리의 종류를 UE5에 알려줍니다. 예를 들어 플레이어의 움직임은 작은 세부 사항에 '고착'되는 것을 방지하기 위해 단순한 기하학적 구조와 충돌합니다.
편집기에는 플레이어가 충돌하는 세계를 볼 수 있는 편리한 보기 모드가 있습니다. (Player Collision)
오버랩 이벤트를 적용하기 위해서는 양쪽 모두 Generate Overlap Events가 활성화 되어 있어야 합니다.
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) 에서 meta=(BlueprintSpawnableComponent)를 통해서 클래스를 블루프린트에서 이 컴포넌트를 생성할 수 있습니다.
최적화의 측면에서 언리얼의 대부분의 컴포넌트는 자동으로 틱이 비활성화되어 있습니다.
액터는 디폴트로 활성화되어 있지만 컴포넌트는 비활성화되어 있습니다
틱이 작동하는 무버와 같은 다른 컴포넌트를 보면 파일 상단에 UMover 함수에서 PrimaryComponentTick.bCanEverTick = true로 설정되어 있습니다.
PrimaryComponentTick
- PrimaryComponentTick은 컴포넌트의 "틱" 또는 업데이트 기능을 관리하는 구조체입니다. 이는 컴포넌트가 매 프레임마다 어떻게 동작할지 결정하는 데 사용됩니다.
PrimaryComponentTick.bCanEverTick
컴포넌트의 틱(업데이트) 동작을 제어하는 데 사용되는 속성입니다. 이 속성은 UPrimitiveComponent 또는 UActorComponent와 같은 컴포넌트 클래스의 인스턴스에 대해 설정될 수 있습니다.
- bCanEverTick은 불리언(Boolean) 타입의 변수로, 컴포넌트가 틱할 수 있는지 여부를 결정합니다.
- true로 설정하면 컴포넌트가 틱할 수 있음을 의미하며, 이는 컴포넌트가 매 프레임마다 Tick 함수를 호출할 수 있음을 나타냅니다.
- false로 설정하면 컴포넌트는 틱하지 않으며, 이는 성능 최적화에 유용할 수 있습니다.
Syntax : uint8 bCanEverTick: 1
UActorComponent::OnComponentDestroyed
이벤트 핸들러 함수로, 컴포넌트가 파괴될 때 호출됩니다. 이 함수는 UActorComponent 클래스의 멤버 함수로, 컴포넌트가 게임 월드에서 제거되거나 파괴될 때 필요한 정리 작업을 수행하는 데 사용될 수 있습니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/Components/ActorComponent.h |
Include | #include "Components/ActorComponent.h" |
Source | /Engine/Source/Runtime/Engine/Private/Components/ActorComponent.cpp |
Syntax
기능 및 사용:
- 컴포넌트 파괴시 호출: OnComponentDestroyed는 컴포넌트가 파괴되는 시점에 자동으로 호출됩니다. 이 함수는 컴포넌트와 관련된 리소스를 해제하거나, 특정 로직을 수행하기 위해 오버라이드(재정의)될 수 있습니다.
- 리소스 정리: 예를 들어, 컴포넌트가 동적으로 생성된 메모리나 다른 리소스를 사용했다면, OnComponentDestroyed에서 이러한 리소스를 적절히 해제하는 코드를 작성할 수 있습니다.
- 상태 업데이트: 컴포넌트와 관련된 게임의 상태나 다른 컴포넌트의 상태를 업데이트하는 데 사용될 수도 있습니다.
주의사항:
- OnComponentDestroyed는 컴포넌트의 생명주기의 일부로서 중요한 함수이므로, 이를 오버라이드할 때는 기본 클래스의 OnComponentDestroyed 함수도 명시적으로 호출해야 할 수 있습니다. 예를 들어, Super::OnComponentDestroyed(bDestroyingHierarchy);와 같이 기본 클래스의 함수를 호출합니다.
PostEditChangeProperty
함수로, 에디터에서 객체의 프로퍼티가 변경되었을 때 호출됩니다. 이 함수는 주로 UObject 클래스나 그 파생 클래스에서 오버라이드되어 사용됩니다. PostEditChangeProperty의 주요 목적은 에디터 내에서 프로퍼티가 변경된 후 필요한 추가 처리나 검증, 업데이트를 수행하는 것입니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h |
Include | #include "GameFramework/Actor.h" |
Source | /Engine/Source/Runtime/Engine/Private/ActorEditor.cpp |
Syntax
virtual void PostEditChangeProperty
(
FPropertyChangedEvent & PropertyChangedEvent
)
주의사항:
- PostEditChangeProperty 함수는 에디터 모드에서만 호출되며, 게임 런타임에서는 호출되지 않습니다.
- 프로퍼티 변경 후 필요한 모든 처리를 적절히 수행하고, 기본 클래스의 PostEditChangeProperty 함수도 호출하는 것이 좋습니다. 이렇게 하면 상속받은 클래스의 필요한 기본 동작도 보장됩니다.
- 프로퍼티 변경이 빈번히 발생하는 경우, 이 함수의 오버헤드가 크기 때문에 성능에 영향을 줄 수 있습니다. 따라서, 필요한 경우에만 로직을 추가하는 것이 좋습니다.
Actor Tag
액터(Actor)에 부여할 수 있는 문자열 기반의 식별자입니다. 이 태그들은 액터를 분류하거나 식별하는 데 사용됩니다. 액터 태그는 게임 로직에서 특정 액터를 쉽게 찾고 구별하는 데 유용하게 사용됩니다.
Tag를 부여할 Actor의 > Tags 에서 "Unlock1"태그 추가 후 아래 코드로 실행부를 구현해 줍니다.
if(Actor->ActorHasTag("Unlock1")){...}
Tag를 Unreal 에디터에서 수정하고 싶을 경우 아래와 같은 변수를 만들어 줍니다.
//.h
private:
UPROPERTY(EditAnywhere)
FName AcceptableActorTag;
//.cpp
if(Actor->ActorHasTag("AcceptableActorTag")){}
태그 관련 함수
- ActorHasTag: 이 함수는 액터가 특정 태그를 가지고 있는지 여부를 확인합니다.
- GetTags: 액터에 설정된 모든 태그를 가져오는 함수입니다.
AActor::ActorHasTag
특정 액터(Actor)가 주어진 태그를 가지고 있는지 여부를 확인합니다. 이 함수는 액터에 할당된 태그 리스트를 검사하여, 지정된 태그가 존재하는지 확인하는 데 사용됩니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h |
Include | #include "GameFramework/Actor.h" |
Source | /Engine/Source/Runtime/Engine/Private/Actor.cpp |
Dependency Injection(의존성 주입)
의존성 주입(Dependency Injection)"이라는 프로그래밍 기법을 통해 게임 내의 무버(Mover)와 트리거(Trigger) 컴포넌트 사이의 연결을 설정하는 방법을 다룹니다. 의존성 주입을 사용하면, 한 컴포넌트가 다른 컴포넌트에 대한 참조를 직접 검색하거나 관리할 필요 없이, 외부(예: 블루프린트나 다른 클래스)에서 필요한 의존성을 제공받을 수 있습니다. 이로써 더 유연하고 관리하기 쉬운 코드 구조를 만들 수 있습니다.
주요 내용 요약:
- 의존성 주입의 필요성:
- Grabber.cpp는 PhysicsHandle 컴포넌트에 의존적입니다. PhysicsHandle이 없으면 Grabber는 작동하지 않습니다.
- 마찬가지로, Trigger 컴포넌트는 Mover 컴포넌트에 접근할 수 있어야 정상적으로 작동합니다.
- 의존성 주입의 이점:
- 트리거와 무버가 같은 액터 내에 있을 때는 액터 내에서 컴포넌트 타입을 통해 쉽게 찾을 수 있지만, 서로 다른 위치에 있을 경우 의존성 주입이 유용합니다.
- 의존성 주입을 사용하면, 트리거가 무버를 직접 찾지 않고도 의존하는 대상을 설정할 수 있습니다.
- 구현 방법:
- TriggerComponent.h에 블루프린트 호출 가능한 함수를 만들어 Mover 컴포넌트의 포인터를 받을 수 있도록 합니다.
- 이를 위해 TriggerComponent 클래스에 SetMover 함수와 Mover 포인터를 추가합니다.
- 추가 구현 사항:
- Mover.h와 Mover.cpp에 ShouldMove라는 불리언 변수를 업데이트하는 SetShouldMove 함수를 추가합니다.
- TriggerComponent.cpp에서 TickComponent 메서드 내에서 Mover의 SetShouldMove 메서드를 호출하여 무버의 상태를 제어합니다.
- 코드의 유연성:
- 블루프린트를 통해 트리거 컴포넌트가 무버를 설정할 수 있도록 하여, 무버와 트리거가 다른 위치에 있어도 효과적으로 작동할 수 있게 합니다.
이 강의의 핵심은 의존성 주입을 통해 컴포넌트 간의 결합도를 낮추고, 더 유연하고 확장 가능한 게임 코드를 작성하는 방법을 배우는 것입니다.
●즉 하나의 Actor에 속해있지 않더라도 Trigger가 움직일 Mover를 블루프린트에서 설정할 수 있게 된다.
// .h
public:
SetMover(UMover* Mover);
private:
UMover* Mover;
//.cpp
SetMover(UMover* NewMover)
{
Mover = NewMover;
}
섀도잉(shadowing)
"섀도잉(shadowing)"은 프로그래밍에서 변수의 범위(scope)와 관련된 개념입니다. 일반적으로 섀도잉은 하나의 스코프 내에서 상위 레벨에 선언된 변수의 이름을 가진 새로운 변수를 선언할 때 발생합니다. 이 경우, 새로운 변수가 상위 레벨의 변수를 "가립니다" 또는 "섀도잉합니다".
섀도잉의 개념
- 변수 섀도잉: 함수나 메서드의 파라미터가 외부 스코프에서 선언된 동일한 이름의 변수를 가리는 경우를 말합니다. 즉, 내부 스코프에서 동일한 이름으로 변수를 선언하면 외부 스코프의 변수는 가려지게 됩니다.
- 메서드에서의 섀도잉: 클래스의 메서드에서 파라미터 이름이 클래스 멤버 변수와 동일하게 사용되면, 메서드 내에서의 이름 참조는 이 파라미터를 가리킵니다. 이로 인해 클래스 멤버 변수에 접근하려면 this 키워드나 다른 구분자를 사용해야 할 수 있습니다.
언리얼 엔진에서의 섀도잉
언리얼 엔진의 C++ 프로그래밍에서는 멤버 변수와 메서드의 파라미터가 동일한 이름을 가지는 것을 피하는 것이 좋습니다. 언리얼 엔진은 이러한 경우를 오류로 간주하지는 않지만, 혼동을 방지하고 코드의 명확성을 유지하기 위해 다음과 같은 관행을 따릅니다:
- 명확한 이름 사용: 멤버 변수와 파라미터 이름을 구분하여 사용하면 코드의 가독성과 관리가 용이해집니다. 예를 들어, 멤버 변수는 MyVariable, 파라미터는 InVariable과 같이 구분할 수 있습니다.
- this 키워드 사용: 클래스의 멤버 변수에 접근할 때 this->VariableName과 같이 this 키워드를 사용하여 명시적으로 멤버 변수임을 나타낼 수 있습니다.
캐스팅과 액터 부착
AActor::AttachToComponent
메서드로, 한 액터(Actor)를 다른 액터의 컴포넌트에 부착하는 기능을 제공합니다. 이 메서드는 주로 하나의 액터를 다른 액터에 "자식"으로 연결할 때 사용되며, 부모 액터의 변화(위치, 회전, 크기 등)에 따라 자식 액터도 함께 움직이도록 만듭니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h |
Include | #include "GameFramework/Actor.h" |
Source | /Engine/Source/Runtime/Engine/Private/Actor.cpp |
Syntax
void AttachToComponent
(
USceneComponent * Parent,
const FAttachmentTransformRules & AttachmentRules,
FName SocketName
)
기능 및 사용
- 액터의 부착: AttachToComponent는 특정 컴포넌트(예: USceneComponent)에 액터를 부착합니다. 부착된 액터는 부모 컴포넌트의 변화에 따라 움직입니다.
- 부모-자식 관계: 이 메서드를 사용하면 부모-자식 관계가 형성되며, 부모 액터의 움직임이나 변화가 자식 액터에게도 적용됩니다.
- 변환(위치, 회전, 크기) 상속: 부모 컴포넌트의 변환에 따라 자식 액터의 위치, 회전, 크기 등이 결정됩니다.
사용 예시
// ParentActor의 일부 컴포넌트에 ChildActor를 부착
AActor* ChildActor = ...; // 자식 액터
USceneComponent* ParentComponent = ...; // 부모 액터의 컴포넌트
FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true);
ChildActor->AttachToComponent(ParentComponent, AttachmentRules);
- 이 예시에서는 ParentComponent에 ChildActor를 부착합니다. FAttachmentTransformRules를 사용하여 부착 시의 변환 규칙(위치, 회전, 크기)을 정의할 수 있습니다. EAttachmentRule::SnapToTarget는 자식 액터를 부모 컴포넌트의 정확한 위치와 회전으로 부착하도록 지정합니다.
주의사항
- 부착된 액터는 부모 컴포넌트의 변환을 따르기 때문에, 독립적인 변환을 적용하려면 먼저 부착을 해제해야 할 수 있습니다.
- 부모 컴포넌트가 없거나 잘못 지정된 경우, AttachToComponent는 실패할 수 있습니다.
- 액터를 부착하는 것은 특히 계층적인 오브젝트 구조를 구성할 때 유용합니다(예: 무기가 캐릭터의 손에 부착되는 경우).
UPrimitiveComponent::SetSimulatePhysics
메서드로, 특정 컴포넌트에 대해 물리 시뮬레이션을 활성화하거나 비활성화하는 기능을 수행합니다. 이 메서드는 주로 UPrimitiveComponent 또는 그 파생 클래스의 인스턴스에서 사용되며, 오브젝트가 물리 엔진의 영향을 받아 자연스럽게 움직이도록 만들거나, 그 반대로 물리 시뮬레이션을 중지할 때 사용됩니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/Components/PrimitiveComponent.h |
Include | #include "Components/PrimitiveComponent.h" |
Source | /Engine/Source/Runtime/Engine/Private/PrimitiveComponentPhysics.cpp |
Syntax
사용 예시
// RootComponent가 UPrimitiveComponent가 아닐 수 있으니 형변환
UPrimitiveComponent* Component = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
if(Component != nullptr)
{
Component->SetSimulatePhysics(false);
}
Actor->AttachToComponent(this, FAttachmenTransformRules::KeepWorldTransform);
Mover->SetShouldMove(true);
C++과 UE5의 캐스팅
C++
C++에서 제공하는 캐스팅(casting) 메커니즘은 타입 간 변환을 위해 사용되며, 다양한 형태가 있습니다. 각 캐스팅 방식은 특정 상황에 적합하게 설계되어 있으며, 사용 목적에 따라 적절한 캐스팅 방법을 선택해야 합니다.
1. static_cast
- 용도: 컴파일 시간에 타입 안전성을 검사하는 기본적인 캐스팅 방법입니다. 서로 관련 있는 타입 간의 변환에 사용됩니다.
- 예시: 기본 타입 간의 변환, 포인터 타입의 상하위 클래스 간 변환.
- 사용법: static_cast<NewType>(variable)
2. dynamic_cast
- 용도: 런타임에 타입 안전성을 검사하는 캐스팅 방법으로, 주로 다형성을 가진 클래스 간의 포인터나 참조에 사용됩니다. 실제 객체 타입을 검사하여 캐스팅의 성공 여부를 결정합니다.
- 예시: 기반 클래스 포인터에서 파생 클래스 포인터로 변환할 때 사용.
- 사용법: dynamic_cast<NewType*>(variable) 또는 dynamic_cast<NewType&>(variable)
- 주의점: dynamic_cast는 RTTI(Runtime Type Information)를 사용하므로 성능 오버헤드가 있을 수 있습니다.
3. const_cast
- 용도: 객체의 const 또는 volatile 속성을 추가하거나 제거할 때 사용합니다. 주로 상수성을 제거하는 데 사용됩니다.
- 예시: const 포인터를 비 const 포인터로 변환.
- 사용법: const_cast<NewType>(variable)
4. reinterpret_cast
- 용도: 서로 관련 없는 타입 간의 변환에 사용됩니다. 비트 단위로 그대로 변환되기 때문에, 다른 캐스팅 방법들보다 덜 안전합니다.
- 예시: 포인터 타입을 다른 타입의 포인터로 변환, 정수를 포인터로 변환.
- 사용법: reinterpret_cast<NewType>(variable)
캐스팅 선택 시 주의사항:
- 타입 안전성: static_cast와 dynamic_cast는 타입 안전성을 제공하며, 가능한 한 이들을 사용하는 것이 좋습니다.
- 성능 고려: dynamic_cast는 런타임에 타입 검사를 수행하기 때문에 성능 오버헤드가 있을 수 있습니다.
- 안전성: reinterpret_cast는 매우 강력하지만 위험할 수 있으므로, 필요한 경우에만 신중하게 사용해야 합니다.
- 상수성 유지: const_cast는 상수성을 제거할 때 사용되지만, 원래 상수로 선언된 객체의 상수성을 제거하여 수정하는 것은 정의되지 않은 동작을 야기할 수 있습니다.
Unreal Engine 5
Cast<>() 함수는 Unreal Engine의 C++ 프로그래밍에서 매우 중요한 기능입니다. 이 함수는 객체의 포인터를 한 타입에서 다른 타입으로 안전하게 변환하는 데 사용됩니다. 주로 객체가 특정 클래스의 인스턴스인지 확인하고, 해당 클래스 타입으로 변환할 때 사용됩니다.
기능 및 사용
- 타입 안전성: Cast<>()는 런타임에 객체의 타입을 확인하여, 요청된 타입으로의 변환이 안전한지 검사합니다. 이는 타입 안전성을 제공하며, 잘못된 타입 캐스트로 인한 오류를 방지합니다.
- 다운캐스팅: 객체의 포인터를 상위 클래스 타입에서 하위 클래스 타입으로 변환하는 과정을 "다운캐스팅"이라고 합니다. Cast<>()는 이러한 다운캐스팅을 안전하게 수행합니다.
사용 예시
AActor* MyActor = ...; // AActor 타입의 포인터
AMyCharacter* MyCharacter = Cast<AMyCharacter>(MyActor);
if (MyCharacter)
{
// 성공적으로 캐스팅되었을 때 수행할 작업
}
- 이 예시에서는 MyActor라는 AActor 타입의 포인터를 AMyCharacter 타입으로 캐스팅하려고 시도합니다. 만약 MyActor가 실제로 AMyCharacter의 인스턴스이거나 그 하위 클래스의 인스턴스라면, 캐스팅은 성공하고 MyCharacter 포인터가 유효한 값을 가집니다. 그렇지 않다면 MyCharacter는 nullptr이 됩니다.
주의사항
- Cast<>()는 포인터 타입에 대해서만 사용됩니다. 참조 타입에는 사용할 수 없습니다.
- Cast<>()는 실패할 경우 nullptr을 반환합니다. 따라서 캐스팅 후 반환된 포인터를 사용하기 전에는 반드시 null 체크를 해야 합니다.
- Cast<>()는 런타임 비용이 발생합니다. 빈번한 캐스팅이 필요한 상황에서는 성능에 영향을 줄 수 있으므로, 캐스팅을 남용하지 않도록 주의해야 합니다.
- Cast<>()는 Unreal Engine의 RTTI(Runtime Type Information) 시스템을 사용합니다. 클래스가 RTTI를 지원해야만 캐스팅이 가능합니다.
Adding and Removing Tags
이번 강의에서는 집고 있는 오브젝트에 태그를 추가해 보겠습니다
가고일을 집고 F8을 눌러 가고일 조각상의 디테일을 보면 보시는 대로 Grabbed 태그가 달려 있습니다
가고일을 놓고 다시 디테일을 보면 태그가 사라졌습니다
현재 가고일을 집고 있으므로 가고일을 잡아챌 수 없다고 씬 내 다른 게임플레이 오브젝트에 알리는 기능입니다
어떻게 이 기능을 구현할 수 있는지 알아보겠습니다
현재 가고일을 트리거 영역에 가져가면 플레이어가 놓기도 전에 트리거 영역에서 가고일을 잡아챕니다.
따라서 들고 있을 때 Grabber Tag를 부착하여 가고일이 붙잡히지 않게 합니다.
// Tag 추가
HitReult.GetActor()->Tags.Add("Grabbed");
// Tag 제거
AActor* GrabbedActor = PhysicsHandle->GetGrabbedComponent()->GetOwner();l
GrabbedActor->Tags.Remove("Grabbed");
AActor().Tags
특정 객체에 태그들의 배열을 저장하는 데 사용됩니다. 이 배열은 FName 타입의 요소들을 포함하며, 주로 객체를 그룹화하고 분류하는 데 사용됩니다.
TArray<FName> Tags
주의사항:
- FName 타입은 일반 문자열(FString)과 다르게 처리되며, 주로 메모리와 성능 최적화를 위해 사용됩니다.
Tags.Add()
Tags.Add()는 Unreal Engine에서 사용되는 TArray 클래스의 멤버 함수입니다. 이 함수는 TArray에 새로운 요소를 추가하는 데 사용됩니다. Tags라는 이름의 TArray 변수가 있다고 가정할 때, Add 메서드를 호출하면 해당 배열의 끝에 새로운 요소를 추가할 수 있습니다.
Tags.Remove()
Tags.Add()는 Unreal Engine에서 사용되는 TArray 클래스의 멤버 함수입니다. 이 함수는 TArray에 새로운 요소를 삭제하는 데 사용됩니다.
AActor::ActorHasTag
메서드로, 특정 AActor 인스턴스가 주어진 태그를 가지고 있는지 여부를 확인하는 데 사용됩니다. 이 함수는 액터의 태그 배열을 검사하여, 지정된 태그가 존재하는지 여부를 반환합니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h |
Include | #include "GameFramework/Actor.h" |
Source | /Engine/Source/Runtime/Engine/Private/Actor.cpp |
주의사항
- ActorHasTag 함수는 액터가 가진 모든 태그를 검사합니다. 따라서, 액터에 여러 태그가 할당된 경우, 모든 태그 중에서 지정된 태그가 하나라도 존재하면 true를 반환합니다.
- 태그는 대소문자를 구별하지 않으므로, 태그를 할당하거나 검사할 때는 이 점을 고려해야 합니다.
AActor::DetachFromActor
AActor::DetachFromActor
메서드로, 한 액터(Actor)를 다른 액터로부터 분리(detach)하는 기능을 수행합니다. 이 함수는 주로 액터가 다른 액터에 부착된 상태(예: AttachToActor 함수를 사용하여 부착된 상태)에서 이를 분리하고자 할 때 사용됩니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h |
Include | #include "GameFramework/Actor.h" |
Source | /Engine/Source/Runtime/Engine/Private/Actor.cpp |
Syntax : void DetachFromActor ( const FDetachmentTransformRules & DetachmentRules)
주의사항
- 분리 작업은 액터의 변환과 관련된 규칙에 따라 다르게 처리될 수 있습니다. 예를 들어, 부모 액터의 상대적인 위치/회전을 유지할 것인지, 월드 좌표계에서의 절대적인 위치/회전을 유지할 것인지를 결정해야 합니다.
FDetachmentTransformRules
액터나 컴포넌트를 다른 액터나 컴포넌트로부터 분리할 때 적용되는 변환(위치, 회전, 크기) 규칙을 정의합니다. 이 구조체는 DetachFromActor 또는 DetachFromComponent 함수와 함께 사용되어, 분리되는 액터나 컴포넌트의 변환 처리 방식을 지정합니다.
References
Module | Engine |
Header | /Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h |
Include | #include "Engine/EngineTypes.h" |
Syntax : struct FDetachmentTransformRules
사용 예시
AActor* ChildActor = ...; // 분리할 자식 액터
// 월드 변환을 유지하면서 액터를 분리
FDetachmentTransformRules DetachmentRules(EDetachmentRule::KeepWorld, true);
ChildActor->DetachFromActor(DetachmentRules);
FDetachmentTransformRules::KeepWorldTransform
열거형 값으로, 액터나 컴포넌트를 다른 액터나 컴포넌트로부터 분리할 때 사용하는 변환(transform) 규칙 중 하나입니다. FDetachmentTransformRules 구조체는 액터나 컴포넌트를 분리할 때 어떻게 변환을 처리할지 정의하는 데 사용됩니다.
KeepWorldTransform의 의미:
- 월드 변환 유지: KeepWorldTransform은 분리되는 액터나 컴포넌트가 부착되었던 상태에서의 월드 변환(위치, 회전, 크기)을 그대로 유지하도록 지시합니다. 즉, 부모 액터로부터 분리된 후에도, 액터나 컴포넌트의 월드 좌표계에서의 위치와 회전은 변경되지 않습니다.
'Unreal 공부 > UE5 GameDev' 카테고리의 다른 글
[UE5] ToonTank (1) (0) | 2023.11.17 |
---|---|
[UE5][개념편] ToonTank (0) | 2023.11.17 |
[UE5] Crypt Raider (1) (0) | 2023.11.11 |
HitResult.Location 과 HitResult.ImpactPoint의 차이 (0) | 2023.11.11 |
LineTraceMultiByChannel의 정의 그리고 SingleByChannel과의 차이점 (0) | 2023.11.11 |