当前位置: 首页 > news >正文

UE5.7编辑器扩展

UE5.7编辑器扩展

过年花了一周用AI + 教程:Create Custom Editor Tools by Vince Petrelli(崇高敬意) 快速搞了一波UE API.毕竟搞游戏的不会点UE API都不好意思打招呼

注:可能跟原教程代码不一样。

2: Actor变换 旋转 WBP + C++

v2

 

#pragma once#include "CoreMinimal.h"
#include "EditorUtilityWidget.h"
#include "QuickActorActionsWidget.generated.h"UENUM(BlueprintType)
enum class E_DuplicateType: uint8
{X UMETA(DisplayName = "X offset"),Y UMETA(DisplayName = "Y offset"),Z UMETA(DisplayName = "Z offset"),
};USTRUCT(BlueprintType)
struct FRandomActorRotation
{GENERATED_BODY();UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform")bool bXRandom{false};UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform")bool bYRandom{false};UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform")bool bZRandom{true};UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform", meta=(EditCondition= "bXRandom"))FVector2f XMinMax{-45,45};UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform", meta=(EditCondition= "bYRandom"))FVector2f YMinMax{-45,45};UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Transform", meta=(EditCondition= "bZRandom"))FVector2f ZMinMax{-45, 45};};UCLASS()
class SUPERMANAGER_API UQuickActorActionsWidget : public UEditorUtilityWidget
{GENERATED_BODY()public:UFUNCTION(BlueprintCallable)void SelectActorsWithSameName();UFUNCTION(BlueprintCallable)void DuplicateActors();UFUNCTION(BlueprintCallable)void RandomRotationActors();UFUNCTION(BlueprintCallable)void ResetRotationActors();UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Duplication")E_DuplicateType DuplicateType = E_DuplicateType::X;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Duplication")int32 CopyNum = 4;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Actor Batch Duplication")float OffsetDist = 300;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "RandomRotationTransform")FRandomActorRotation RandomRotation;private:UPROPERTY()class UEditorActorSubsystem *EditorActorSubsystem;void GetEditorActorSubsystem();
};

cpp:

// Fill out your copyright notice in the Description page of Project Settings.
#include "ActorActions/QuickActorActionsWidget.h"#include "DebugHeader.hpp"
#include "Subsystems/EditorActorSubsystem.h"void UQuickActorActionsWidget::GetEditorActorSubsystem()
{if (not EditorActorSubsystem)EditorActorSubsystem = GEditor->GetEditorSubsystem<UEditorActorSubsystem>();
}void UQuickActorActionsWidget::SelectActorsWithSameName(){Print(FColor::Black,"start select same name actors");GetEditorActorSubsystem();auto actors = EditorActorSubsystem->GetSelectedLevelActors();if (actors.IsEmpty()){ShowNotifyInfo("No Selection, Please Select one actor");return;}if (actors.Num() > 1){ShowNotifyInfo("Please Select one actor");return;}FString selectActorLabel = actors[0]->GetActorLabel();FString nameToSearch = selectActorLabel.LeftChop(3);// 去除尾
    Print(FColor::Green,nameToSearch);for (auto *actor: EditorActorSubsystem->GetAllLevelActors()){if (not actor->GetActorLabel().Contains(nameToSearch)) continue;EditorActorSubsystem->SetActorSelectionState(actor, true);}//EditorActorSubsystem->SetSelectedLevelActors(ActorsToSelect);
}void UQuickActorActionsWidget::DuplicateActors(){auto calOffsetLocation = [this](int incrementNum){FVector offsetLocation{0,0,0};switch (DuplicateType){case E_DuplicateType::X:offsetLocation.X = OffsetDist * (incrementNum+1);break;case E_DuplicateType::Y:offsetLocation.Y = OffsetDist * (incrementNum+1);break;case E_DuplicateType::Z:offsetLocation.Z = OffsetDist * (incrementNum+1);break;default:break;}    return offsetLocation;};for (auto *actor: EditorActorSubsystem->GetSelectedLevelActors()){for (int i=0;i<CopyNum;i++){auto *copyedActor = EditorActorSubsystem->DuplicateActor(actor);copyedActor->AddActorLocalOffset(calOffsetLocation(i));}}
}void UQuickActorActionsWidget::RandomRotationActors()
{for (auto *actor: EditorActorSubsystem->GetSelectedLevelActors()){if (RandomRotation.bXRandom) // Roll
        {auto v = FMath::RandRange(RandomRotation.XMinMax.X, RandomRotation.XMinMax.Y );actor->AddActorLocalRotation(FRotator{0,v,v});}if (RandomRotation.bYRandom) // Pitch
        {auto v = FMath::RandRange(RandomRotation.YMinMax.X, RandomRotation.YMinMax.Y );actor->AddActorLocalRotation(FRotator{v,v,0});}if (RandomRotation.bZRandom) // YAW
        {auto v = FMath::RandRange(RandomRotation.ZMinMax.X, RandomRotation.ZMinMax.Y );actor->AddActorLocalRotation(FRotator{0,v,0});}}
}void UQuickActorActionsWidget::ResetRotationActors(){for (auto *actor: EditorActorSubsystem->GetSelectedLevelActors()){actor->SetActorRotation(FRotator{0,0,0});}
}

 

 

 

 

 

 

3: 子Menu创建:扩展ActorAsset 对着视窗一个Actor鼠标右键:

image

 

#pragma oncestruct BuildActorActions
{void Init();void ShutDown();
private:void InitLevelEditorExtension();void AddMenuEntry(FMenuBuilder& MainMenu);void buildSubMenu(FMenuBuilder& subMenu);void onLockActorSelectionButtonClicked();void onUnlockActorSelectionButtonClicked();// Selection Eventvoid InitCustomSelectionEvent(); 
};

cpp:

#include "ActorActions/BuildActorActions.h"#include "DebugHeader.hpp"
#include "LevelEditor.h"
#include "Selection.h"void BuildActorActions::Init()
{//GEngine
    InitCustomSelectionEvent();InitLevelEditorExtension();
}void BuildActorActions::ShutDown()
{}void BuildActorActions::InitLevelEditorExtension()
{auto &levelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));TArray<FLevelEditorModule::FLevelViewportMenuExtender_SelectedActors> &levelMenuExtenders = levelEditorModule.GetAllLevelViewportContextMenuExtenders();levelMenuExtenders.Add(FLevelEditorModule::FLevelViewportMenuExtender_SelectedActors::CreateLambda([this](const TSharedRef<FUICommandList> guiCommandList, const TArray<AActor*> SelectedActors){// Ret: TSharedRef<FExtender>TSharedRef<FExtender> extender = MakeShareable(new FExtender());if (SelectedActors.IsEmpty()) return extender;extender->AddMenuExtension(FName{"ActorOptions"}, EExtensionHook::Before,guiCommandList,FMenuExtensionDelegate::CreateRaw(this,&BuildActorActions::AddMenuEntry) );return extender;}));
}void BuildActorActions::AddMenuEntry(FMenuBuilder& MainMenu)
{/** NSLOCTEXT( Namespace, Key, DefaultText )* Namespace(命名空间):用于组织文本的逻辑分组,避免不同模块间的 Key 冲突(通常使用模块名或功能名)。Key(键):该文本的唯一标识符,在同一命名空间下必须唯一。DefaultText(默认文本):开发时使用的源语言文本(例如英语),在翻译文件中会以此为基础生成其他语言的版本。* */MainMenu.AddSubMenu(NSLOCTEXT("BuildActorActions", "Actor Action Extensions", "Actor Action Extensions"),NSLOCTEXT("BuildActorActions", "SubMenu1Tooltip", "First sub action"),FNewMenuDelegate::CreateRaw(this, &BuildActorActions::buildSubMenu) );
}void BuildActorActions::buildSubMenu(FMenuBuilder& subMenu)
{subMenu.AddMenuEntry(NSLOCTEXT("BuildActorActions", "Lock Actor Selection", "Lock Actor Selection"),NSLOCTEXT("BuildActorActions", "Command1Tooltip", "Execute Command A"),FSlateIcon(), FExecuteAction::CreateRaw(this, &BuildActorActions::onLockActorSelectionButtonClicked));subMenu.AddMenuEntry(NSLOCTEXT("BuildActorActions", "Unlock Actor Selection", "Unlock Actor Selection"),NSLOCTEXT("BuildActorActions", "Unlock Actor Selection", "Execute Command A"),FSlateIcon(), FExecuteAction::CreateRaw(this, &BuildActorActions::onUnlockActorSelectionButtonClicked));}void BuildActorActions::onLockActorSelectionButtonClicked(){Print(FColor::Green, "Locked");
}
void BuildActorActions::onUnlockActorSelectionButtonClicked(){Print(FColor::Green, "UnLocked");
}void BuildActorActions::InitCustomSelectionEvent()
{USelection *UserSelection = GEditor->GetSelectedActors();UserSelection->SelectObjectEvent.AddLambda([](UObject* selectObj){Print(FColor::Green, selectObj->GetName());});
}