Unreal

7. Expose Variable & Function, Template Function, Components

Kelvin의 게임개발 2023. 12. 14. 01:03
728x90
반응형

1. Expose Variable To BP

 

변수를 BP에 노출시키면 BP의 DetailTab에서 제어가 가능하다


월드에 배치된 Actor를 선택하고 각각의 변수값을 DetailTab에서 변경할 수 있다

 

UPROPERTY()키워드로 해당 변수를 ReflectionSystem으로 제어할 수 있게 해준다

 

UPROPERTY()변수들은 전부 0으로 초기화가 된다

 

UPROPERTY(EditDefaultsOnly) //BP Class의 DetailTab에서만 값 수정이 가능하다 (월드에 배치된 Actor Instance의 DetailTab에서는 수정이 불가하다)
float Amplitude = 0.25f;

UPROPERTY(EditInstanceOnly) //World에 배치된 Actor Instance의 DetailTab에서만 값 변경이 가능하다 BP Class에서 변경은 불가능함
float TimeConstant = 0.5f;

UPROPERTY(EditAnywhere) //BP Class, Actor Instance 둘 다 DetailTab에서 값 변경이 가능하다
float Amplitude = 0.25f;

 

UPROPERTY(EditDefaultsOnly)로 BP Class에서만 값 수정이 가능하다

 

UPROPERTY(EditInstanceOnly)로 Actor Instance에서만 값 수정이 가능하다 (화살표로 기본값으로 돌아갈 수 있다)

 

UPROPERTY(VisibleDefaultsOnly) //BP Class의 DetailTab에 변수가 노출되지만 수정할 수 없다
float RunningTime;

UPROPERTY(VisibleInstanceOnly) //월드에 배치된 Actor Instance의 DetailTab에 변수가 노출되지만 수정할 수 없다
float RunningTime;

UPROPERTY(VisibleAnywhere) //BP Class, Actor Instance 둘 다 DetailTab에 변수가 노출되지만 수정할 수 없다
float RunningTime;

UPROPERTY(Visible...)키워드로 수정이 비활성화 되어있다

 

변수를 BP의 EventGraph에서 사용하고 싶다면 다음과 같은 UPROPERTY()지정자가 필요하다

//변수가 Private으로 선언되면 사용이 불가능하다

UPROPERTY(BlueprintReadOnly) //BP에서 Getter만 사용 가능
float Amplitude = 0.25f;

UPROPERTY(BlueprintReadWrite) //BP에서 Getter/Setter 둘 다 사용 가능하다
float Amplitude = 0.25f;


//Private에 선언된 변수를 BP의 EventGraph에서 사용하고 싶다면 meta지정자를 이용해야 한다
private:
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	float Amplitude = 0.25f;

 

Visible지정자, Read지정자는 ,로 구분지어 함께 사용이 가능하다

UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
float Amplitude = 0.25f;

 

BP에 변수가 노출될 때 Category도 지정이 가능하다

UPROPERTY(BlueprintReadWrite, Category = "Sine Param") //Sine Param이라는 카테고리가 생성되고 하위에 변수가 노출된다
float Amplitude = 0.25f;

 

Sine Param이라는 카테고리가 추가됨

 

Clamp : Input값의 최소값, 최대값을 지정할 수 있다 값이 최소값보다 작아지거나 최대값보다 작아지면 해당 min,max값을 반환하며 아니면 value값을 반환한다

 

Input값 (float), Min값 (float), Max값 (float)을 인자로 가진다

 

 

2. Expose Function To BP

 

변수뿐만 아니라 함수도 BP에 노출시킬 수 있다

 

UFUNCTION(BlueprintCallable) //BP에서 함수를 호출할 수 있게 해준다
float TestFunction(float InValue) { return InValue; }

BP에서 노드로 사용이 가능해진다

 

이때 BP에서 입력/출력 핀이 없는 노드로 만들고 싶다면 아래와 같이 처리한다

UFUNCTION(BlueprintCallable, BlueprintPure) //BP 노드에서 입/출력 핀이 없는 pure함수로 만든다
float TestFunction(float InValue) { return InValue; }

 

 

3. Template Function

 

template함수는 함수를 여러 타입별로 개별적으로 작성하지 않아도, 여러 타입으로 사용할 수 있도록 하게 만들어 놓은 틀 이다

 

//template함수 선언
template<typename T>
T Avg(T First, T Second);

//template함수 정의
template<typename T>
inline T AItems::Avg(T First, T Second)
{
	return T();
}

//template함수 호출
//함수이름<타입>(매개변수,매개변수...);

int32 AvgInt = Avg<int32>(1, 3); //T에 int32가 적용되고 매개변수로 1,3이 들어간다
float AvgFloat = Avg<float>(3.4f, 7.8f); //T에 float이 적용되고 매개변수로 3.4, 7.8이 들어간다

 

template함수 구현을 적용할 수 있는 타입은 전부 가능하다

(ex) FRotator는 /이 불가능하다 -> / operator가 없기 때문 -> Avg() T에 사용이 불가능하다)

 

inline이란 컴파일러가 함수 바디를 컴파일 타임에 붙여 넣어 함수 호출의 오버헤드를 줄이는 최적화 방식이다

 

 

4. Component

 

Component는 Actor를 구성하는 부품이라 생각하면 된다
ex) MeshComponent로 Actor 시각화, Collision Component로 충돌체크 등등

Actor를 생성하면 기본적으로 Default Scene Root라는 컴포넌트가 생성된다 (RootComponent)

 

Component 추가는 +Add 버튼으로 할 수 있다


SceneComponent는 USceneComponent타입이다 (Actor가 아닌 UObject를 상속받음)
SceneComponent는 Transform을 가지고 있다 (Location(FVector), Rotation(FRotator), Scale(FVector)
SceneComponent가 Transform을 가지고 있기 때문에 GetActorLocation()시 RootComponent의 Location을 가져올 수 있는것이다


SceneComponent는 다른 Component에 attach될 수 있다

RootComponent에 다른 Component가 붙으면 이동할때 붙은 Component는 따라다니게 된다 (Offset을 줄 수 있다)

UStaticMeshComponent는 USceneComponent를 상속받은 컴포넌트 클래스이다

 

따라서 StaticMeshComponent도 Transform을 가지고 다른 Component에 attach될 수 있으며 RootComponent로 사용이 가능하다 (드래그 드랍으로 RootComponent지정이 가능하다, 단 RootComponent는 기즈모로 이동이 불가능하다)

 

StaticMeshComponent는 UStaticMesh타입 변수를 가지고 있다 (Mesh)

여기서 원하는 Mesh를 선택하여 외형을 변경할 수 있다

 

Pivot이 항상 가운데에 있는게 아니다

 

 

5. Component C++

 

모든 언리얼 오브젝트 실행 초기 런타임 과정에서 UClass Instance, Unreal Object Instance를 생성한다

Unreal Object Instance는 UnrealObject의 기본 세팅을 지정하고 클래스 기본 객체(Class Default Object, CDO)라고 한다


CDO를 만드는 이유는, 언리얼 오브젝트를 생성할 때마다 매번 초기화 하지않고, 기본 인스턴스를 미리 만들어 놓고 복제해서 사용하기 위함이다 크고 복잡한 오브젝트를 매번 생성하는 것보다 복제 후 속성만 변경하여 사용하는 것이 효과적이기 때문이다

Unreal Object의 Construct(생성자)는 CDO를 제작하기 위한 목적으로 사용된다

실제 게임 플레이에서 생성자 코드는 사용할 일이 없다고 보면 된다

 

참고로 언리얼 엔진에서 게임 플레이에서 사용할 초기화 함수는 생성자 대신 Init 이나 혹은 BeginPlay 함수를 제공한다

 

 

Component를 추가할 때 CDO와 마찬가지로 DefaultSubObject를 생성해야 한다


DefaultSubobject를 생성할 때 몇가지 정보를 제공해야 한다
첫번째로 Object Type과 InternalName을 제공해야한다 (여기서 이름은 Variable Name이 아닌 하위 오브젝트를 생성하기 위해 사용되는 이름이다)

 

이때 Template Function을 사용하게 된다 (template이기 때문에 여러 타입을 넣을 수 있다)

 

ItemMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ItemMeshComponent"));

CreateDefaultSubobject<>() : Component SubObject를 생성하고 Type*으로 반환한다

 

<컴포넌트타입>지정이 필요하고, InternalName (TEXT(" "))를 인자로 가진다

 

 

이렇게 생성을 하면 Type* 변수로 반환한다

 

//.h
private:
	UPROPERTY(VisibleAnywhere) //Reflection System을 해당 포인터 변수가 참조/사용되는지 체크 후 GarbageCollecting한다
	UStaticMeshComponent* ItemMesh;
    
//.cpp
AItems::AItems()
{
	PrimaryActorTick.bCanEverTick = true;

	//Type*으로 반환하기 때문에 UStaticMeshComponent* 변수에 할당할 수 있다
	ItemMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ItemMeshComponent"));

	//RootComponent 지정
	RootComponent = ItemMesh;
}

StaticMeshComponent가 생성되었고 RootComponent로 지정되었다

 

 

 

728x90
반응형

'Unreal' 카테고리의 다른 글

9. The Pawn Class & Enhanced Input System (1)  (67) 2024.01.03
8. The Pawn Class (1)  (179) 2023.12.15
6. Moving Object & Trig Function(삼각함수)  (131) 2023.12.08
5. Actor Class & Debug(2)  (42) 2023.12.05
4. Actor Class & Debug(1)  (1) 2023.12.05