티스토리 뷰
에셋의 복제가 아닌 에디터 상에 있는 물체의 복제를 진행한다.
언리얼에는 4가지 서브시스템이 있음.
UEngineSubsystem, UEditorSubsystem, UGameInstanceSubsystem, ULocalPlayerSubsystem
우리가 사용하는 건 UEditorSubsystem이 된다. 이 서브시스템 하위의 UEditorActorSubsystem을 사용한다.
이 서브시스템에서는 우리는 GetSelectedLevelActors() 와 GetAllLevelActors() 함수를 사용하게 된다.
이 함수들은 static이 아니기 때문에 액세스 하기 위해서는 서브 시스템을 확보해야한다.
#include "Subsystems/EditorActorSubsystem.h"
bool UQuickActorActionsWidget::GetEditorActorSubsystem()
{
if (!EditorActorSubsystem)
{
EditorActorSubsystem = GEditor->GetEditorSubsystem<UEditorActorSubsystem>();
}
return EditorActorSubsystem != nullptr;
}
EditorActorSubsystem 라는 서브시스템은 GEditor 에 접근해서 UEditorActorSubsystem 에디터 서브시스템을 가져올 수 있다.
레벨 내부에서 비슷한 이름을 가진 모든 액터를 선택하기를 원함. 액터 이름을 사용. 기존에 사용하던 에셋 이름과는 다름. 이를 ActorLabel 이라고 부름. (액터이름). 그래서 액터를 선택하려면 GetName이 아니라 GetActorLabel 을 해야함.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ActorBatchSelection")
TEnumAsByte<ESearchCase::Type> SearchCase = ESearchCase::IgnoreCase;
위의 TEnumAsByte<ESearchCase::Type> 를 if(Actor->GetActorLabel().Contains(NameToSearch, SearchCase)) 안에 넣으면 대소문자들에 대한 검색도 활성화/비활성화 할 수 있게 된다.
비슷한 이름을 가진 액터들을 전부 선택하는 함수.
void UQuickActorActionsWidget::SelectAllActorWithSimilarName()
{
if (!GetEditorActorSubsystem()) return;
TArray<AActor*> SelectedActors = EditorActorSubsystem->GetSelectedLevelActors();
uint32 SelectionCounter = 0;
if (SelectedActors.Num() == 0)
{
DebugHeader::ShowNotifyInfo(TEXT("No Actor Selected."));
return;
}
if (SelectedActors.Num() > 1)
{
DebugHeader::ShowNotifyInfo(TEXT("You can onlt Select one actor."));
return;
}
FString SelectedActorName = SelectedActors[0]->GetActorLabel();
const FString NameToSearch = SelectedActorName.LeftChop(4);
TArray<AActor*> AllLevelActors = EditorActorSubsystem->GetAllLevelActors();
for (auto Actor : AllLevelActors)
{
if (!Actor) continue;
if (Actor->GetActorLabel().Contains(NameToSearch, SearchCase))
{
EditorActorSubsystem->SetActorSelectionState(Actor, true);
SelectionCounter++;
}
}
if (SelectionCounter > 0)
{
DebugHeader::ShowNotifyInfo(TEXT("Successfully selected ") + FString::FromInt(SelectionCounter)
+ TEXT(" actors."));
}
else
{
DebugHeader::ShowNotifyInfo(TEXT("No Actor with similar name found."));
}
}
위에서 언급한 GetActorLabel 을 이용하여 현재 엑터의 이름을 가져오고 (배치되는 물체들은 뒤에 숫자만 붙기 때문) 앞 부분을 가지고 비슷한 액터를 찾는다. 이름만 비슷하면 전부 찾는 것이므로 원하지 않는 물체를 선택할수도 있게됨.
그러나 이 부분은 일단 감안하고 넘어간다.
그러면 이렇게 하나의 물체를 클릭하고 버튼 (위젯 만드는 방법은 생략) 을 누르면 같은 이름의 액터들을 모두 선택하게 된다.
이제 물체 복제를 진행.
EditorActorSubsystem 에서 DuplicateActor를 사용한다. 만들어진 엑터를 가지고 x,y,z 방향으로의 확장을 골라서 복제가능하다.
코드가 어렵진않아서 코드를 올린다.
void UQuickActorActionsWidget::DuplicateActors()
{
if (!GetEditorActorSubsystem()) return;
TArray<AActor*> SelectedActors = EditorActorSubsystem->GetSelectedLevelActors();
uint32 Counter = 0;
if (SelectedActors.Num() == 0)
{
DebugHeader::ShowNotifyInfo(TEXT("No Actor Selected."));
return;
}
if (NumberOfDuplicates <= 0 || OffsetDist == 0.f)
{
DebugHeader::ShowNotifyInfo(TEXT("Did not specift a number of duplications or an offset distance"));
return;
}
for (auto SelectedActor : SelectedActors)
{
if (!SelectedActor) continue;
for (int32 i = 0; i < NumberOfDuplicates; i++)
{
AActor* DuplicatedActor =
EditorActorSubsystem->DuplicateActor(SelectedActor, SelectedActor->GetWorld());
if (!DuplicatedActor) continue;
const float DuplicationOffsetDist = (i + 1) * OffsetDist;
switch (AxisForDuplication)
{
case E_DuplicationAxis::EDA_XAxis:
DuplicatedActor->AddActorWorldOffset(FVector(DuplicationOffsetDist, 0.f, 0.f));
break;
case E_DuplicationAxis::EDA_YAxis:
DuplicatedActor->AddActorWorldOffset(FVector(0.f, DuplicationOffsetDist, 0.f));
break;
case E_DuplicationAxis::EDA_ZAxis:
DuplicatedActor->AddActorWorldOffset(FVector(0.f, 0.f, DuplicationOffsetDist));
break;
case E_DuplicationAxis::EDA_MAX:
break;
default:
break;
}
EditorActorSubsystem->SetActorSelectionState(DuplicatedActor, true);
Counter++;
}
}
if (Counter > 0)
{
DebugHeader::ShowNotifyInfo(TEXT("Successfully Duplicated ") + FString::FromInt(Counter)
+ TEXT(" actors."));
}
}
그리고 복제 버튼을 누르면 복제된다. 위의 움짤은 Y 방향으로의 복제.
위의 사진은 z 방향으로의 복제가 이루어졌을 때 이다.
'Unreal > Custom Editor' 카테고리의 다른 글
[UE 5.1] Actor Randomize Transform (0) | 2023.10.30 |
---|---|
[UE 5.1] Custom Material Tool - 2 (1) | 2023.10.13 |
[UE 5.1] Custom Material Tool - 1 (0) | 2023.10.11 |
[UE 5.1] Custom Icon (0) | 2023.09.20 |
[UE 5.1] Custom Slate Widget 04 (0) | 2023.09.19 |
- Total
- Today
- Yesterday
- FPS
- 해시
- LV2
- DFS
- IMGUI
- 탐욕법
- level3
- 고득점kit
- 개인공부
- Ue
- 프로그래머스
- 디자인 패턴
- 누적합
- UE5
- 스택/큐
- C++
- 완전탐색
- 재귀
- 데디케이티드
- sort
- 너비우선탐색
- BFS
- greedy
- LV3
- 고득점 Kit
- Heap
- 채팅서버
- 정렬
- 힙
- Unreal 5.1
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |