UMG在UEC++的使用

参考文章:

【虚幻4】UE4初学者系列教程合集-全中文新手入门教程

UMG使用实例(C++)

UEC++如何绑定UI事件

UMG在UEC++中的基本使用与UI的拖拽事件

UE5 Enhanced Input 输入增强系统学习

UE5增强输入系统实现组合按键

UMG按钮事件实现

UI绑定

在C++中设置UMG的样式并不方便,我们选择在蓝图中设置样式,然后在C++中实现方法

创建一个继承于UserWidget的C++类和蓝图类

image-20250709113653007

然后根据创建好的C++类,生成一个对应的蓝图类

image-20250709113816293

[!Warning]

在蓝图类中编辑好对应的样式,注意左侧按钮的命名,要与在C++中的变量名相同

image-20250709114035367

MyUserWidget.h

public:

	// 定时器句柄
	FTimerHandle TimerHandle;
	
	UPROPERTY(meta=(BindWidget))
	class UButton* Button_Start;

	UPROPERTY(meta=(BindWidget))
	class UButton* Button_Set;

	UPROPERTY(meta=(BindWidget))
	class UButton* Button_Quit;

	virtual void NativeConstruct() override;

	UFUNCTION()
	void Delay();

	UFUNCTION()
	void OnClickedStart();

	UFUNCTION()
	void OnClickedQuit();

	class AAStar_test2Character* player;
	class APlayerController* FirstPlayerController;

在cpp中绑定按钮的点击事件UMyUserWidget.cpp

void UMyUserWidget::NativeConstruct()
{
	Super::NativeConstruct();
	
	Button_Start->OnClicked.AddDynamic(this, &UMyUserWidget::OnClickedStart);
	Button_Quit->OnClicked.AddDynamic(this, &UMyUserWidget::OnClickedQuit);
}

按钮的点击方法实现

void UMyUserWidget::OnClickedStart()
{
	RemoveFromParent();
	
	// find player who`s type is AAStar_test2Character
	player = nullptr;
	for (TActorIterator<AAStar_test2Character> It(GetWorld()); It; ++It)
	{
		player = *It;

		// 返回true,是同一个类型
		if (player->IsA(AAStar_test2Character::StaticClass())) UE_LOG(LogTemp, Warning, TEXT("是同一个类型,%s"),*player->GetName());
		
		if (player && player->GetName().Contains("BP_TopDownCharacter"))
		{
			UE_LOG(LogTemp, Warning, TEXT("Found BP_TopDownCharacter: %s"), *player->GetName());
			break;
		}
	}
	if (!player)
	{
		UE_LOG(LogTemp, Warning, TEXT("未找到名为 BP_TopDownCharacter 的 Actor"));
	}
	UE_LOG(LogTemp, Warning, TEXT("the type of player is : %s"), *player->GetName());
	// getPlayerController
	FirstPlayerController = GetWorld()->GetFirstPlayerController();
	
	FirstPlayerController->SetViewTargetWithBlend(player, 1.0f);

	GetWorld()->GetTimerManager().SetTimer(TimerHandle,this,&UMyUserWidget::Delay,1.0f,false);
	
}

void UMyUserWidget::Delay()
{
	UE_LOG(LogTemp, Log, TEXT("delay 1 second"));
	FirstPlayerController->Possess(player);
	FirstPlayerController->SetShowMouseCursor(true);
}


void UMyUserWidget::OnClickedQuit()
{
	UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}

在关卡蓝图中设置UMG的出现

image-20250709114434619

设置开始的摄像头,创建一个pawn类型的蓝图,然后在蓝图中仅放置一个摄像机,放置在直接中,设置posses为player0即可。参考【虚幻4】UE4初学者系列教程合集-全中文新手入门教程

实现效果

video_20250709_114940_edit

UI动画和暂停游戏

与个UMG同理,创建一个继承自 UserWidget的C++类,并生成对应的蓝图类

image-20250710164930325

暂停UMG的逻辑实现

Pause.h

// 定时器句柄
	FTimerHandle TimerHandle;

	// 绑定按钮
	UPROPERTY(meta=(BindWidget))
	class UButton* Quit;

	// 绑定按钮
	UPROPERTY(meta=(BindWidget))
	class UButton* Continue;

	// 绑定动画
	UPROPERTY(meta = (BindWidgetAnim), Transient)
	class UWidgetAnimation* Appear;

	virtual void NativeConstruct() override;

	UFUNCTION()
	void OnClickedContinue();

	UFUNCTION()
	void OnClickedQQuit();

	UFUNCTION()
	void PlayTheAnimation();

	UFUNCTION()
	void PauseDelay();

	class AAStar_test2Character* player;
	class APlayerController* FirstPlayerController;

Pause.cpp

void UPause::NativeConstruct()
{
	Super::NativeConstruct();

	
	if (Continue)
		Continue -> OnClicked.AddDynamic(this, &UPause::OnClickedContinue);
	else UE_LOG(LogTemp, Log, TEXT("Continue is not alive"));

	if (Quit)
		Quit -> OnClicked.AddDynamic(this, &UPause::OnClickedQQuit);
	else UE_LOG(LogTemp, Log, TEXT("Quit is not alive"));
	
	

}

void UPause::OnClickedContinue()
{
	UE_LOG(LogTemp, Warning, TEXT("触发OnClickedContinue"));
	FirstPlayerController = GetWorld()->GetFirstPlayerController();
	// FirstPlayerController -> SetShowMouseCursor(false);
	FirstPlayerController -> SetInputMode(FInputModeGameOnly());
	UGameplayStatics::SetGamePaused(GetWorld(),false);
	PlayAnimation(Appear, 0.0f, 1, EUMGSequencePlayMode::Reverse, 0.75f, true);
	GetWorld()->GetTimerManager().SetTimer(TimerHandle,this,&UPause::PauseDelay,0.75f,false);
	
}

void UPause::PauseDelay()
{
	SetVisibility(ESlateVisibility::Collapsed);
	StopAnimation(Appear);
}

void UPause::PlayTheAnimation()
{
	// InAnimation, StartAtTime = 0.0f,NumLoopsToPlay = 1, EUMGSequencePlayMode::Type PlayMode = EUMGSequencePlayMode::Forward, float PlaybackSpeed = 1.0f, bool bRestoreState = false)
	PlayAnimation(Appear, 0.0f, 1, EUMGSequencePlayMode::Forward, 0.75f, true);
}



void UPause::OnClickedQQuit()
{
	UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}

在playerController中设置相关事件

主要包括Widget的初始化和键盘事件的绑定和触发

PlayerController.h

	// 绑定按钮使用
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	UInputAction* SetInputQAction;    
	
	// 创建Widget使用
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TSubclassOf<class UPause> PauseWidgetClass;

    UPROPERTY()
    class UPause* PauseWidget;


private:
    
	// 设置初始化Widget
    void SetupPauseWidget();
	
	// 点击事件触发
    void OnPause();

PlayerController.cpp

void AAStar_test2PlayerController::BeginPlay()
{
	// Call the base class  
	Super::BeginPlay();
	
	SetupPauseWidget();
}



void AAStar_test2PlayerController::SetupPauseWidget()
{
	if (PauseWidgetClass)
	{
		UE_LOG(LogTemp, Warning, TEXT("PauseWidgetClass存在"));
		PauseWidget = CreateWidget<UPause>(this, PauseWidgetClass);
		if (PauseWidget)
		{
			UE_LOG(LogTemp, Warning, TEXT("PauseWidget存在"));
			PauseWidget->AddToViewport();
			PauseWidget->SetVisibility(ESlateVisibility::Collapsed);
		}
	}
}

void AAStar_test2PlayerController::OnPause()
{
	UE_LOG(LogTemp, Warning, TEXT("按Q,开始执行Pause"));
	bool isPlaying = PauseWidget -> IsAnimationPlaying(PauseWidget->Appear);
	if (!isPlaying)
	{
		UE_LOG(LogTemp, Warning, TEXT("没有播放动画,走动画"));
		UE_LOG(LogTemp, Warning, TEXT("%s"), *PauseWidget->GetName());
		PauseWidget -> SetVisibility(ESlateVisibility::Visible);
		PauseWidget -> PlayTheAnimation();
		APlayerController* FirstPlayerController = GetWorld()->GetFirstPlayerController();
		// FirstPlayerController->SetShowMouseCursor(true);
		FirstPlayerController->SetInputMode(FInputModeUIOnly());
		UGameplayStatics::SetGamePaused(GetWorld(),true);
	}
}

// 绑定暂停键 Q
void AAStar_test2PlayerController::SetupInputComponent()
{
	// set up gameplay key bindings
	Super::SetupInputComponent();

	// Add Input Mapping Context
	if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
	{
		Subsystem->AddMappingContext(DefaultMappingContext, 0);
	}

	// Set up action bindings
	if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
	{
		// 绑定暂停键 Q
		EnhancedInputComponent->BindAction(SetInputQAction, ETriggerEvent::Started, this, &AAStar_test2PlayerController::OnPause);
		
	}
	else
	{
		UE_LOG(LogTemplateCharacter, Error, TEXT("'%s' Failed to find an Enhanced Input Component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this));
	}
}

蓝图上的设置

UI界面的设置参考:https://www.bilibili.com/video/BV164411Y732?spm_id_from=333.788.videopod.episodes&vd_source=6d070e5f2a4f28fd128440195fce3d9a&p=63

因为使用的是UE5的增强输入,故按键的绑定事件需要额外添加蓝图文件

首先新建一个输入操作

image-20250710170215022

找到对应的全局InputMappingContext(IMC),在里面添加新的操作

image-20250710170342023

最后绑定输入操作到IMC中,在PlayerController的细节面板中,绑定即可。同时我这里绑定了在PlayerController.h中创建的TSubclassOf PauseWidgetClass;

image-20250710170629377

实现效果

2025-07-10 17-14-52

<think>好的,我现在需要帮助用户解决在UE C++中设置按钮颜色的问题。首先,我得回想一下用户提供的引用内容,看看是否有相关的信息。用户提到了引用[2]和引用[3],但主要是关于日志和组件的,可能和UI按钮颜色设置没有直接关联。不过,我需要结合自己的知识来回答。 首先,UE中的按钮通常属于UMG控件,即用户界面元素。设置按钮颜色可能需要操作Slate或UMG的相关API。在C++中,按钮通常是通过UButton类或者其子类来处理的。要设置颜色,可能需要访问按钮的样式或者背景颜色属性。 步骤一:获取按钮的引用。通常在C++中,按钮会被声明为UButton*类型的变量,并在Widget蓝图中进行绑定。例如,使用UPROPERTY()宏和BindWidget标签来绑定到蓝图中的按钮实例。 步骤二:修改按钮的样式。UButton的样式由FButtonStyle结构体控制,其中包含Normal、Hovered、Pressed等状态的外观。要改变颜色,可能需要修改这些状态的背景颜色或图片。 步骤三:使用SetStyle方法。通过创建新的FButtonStyle实例,设置各个状态的颜色,然后调用按钮的SetStyle方法应用新样式。例如,设置Normal状态的ColorAndOpacity为红色。 另外,如果用户只是想简单修改背景颜色,可能需要检查是否有直接设置颜色的属性。不过根据UE的文档,可能需要通过Slate样式来调整,或者使用SetColorAndOpacity方法,但这个方法可能属于UTextBlock或其他子控件,而不是按钮本身。 可能还需要考虑按钮的背景图片,通过设置图片的TintColor来改变颜色。例如,如果按钮有一个背景图像,可以修改其着色。 另外,引用[4]提到使用ActorComponent,但这可能与UI组件无关,所以可能不需要考虑这部分。 总结可能的步骤: 1. 在C++中获取按钮的UButton指针。 2. 创建新的FButtonStyle实例,并设置各个状态的颜色。 3. 使用SetStyle将新样式应用到按钮。 4. 或者,如果有背景图像,修改其TintColor。 还需要注意,动态修改按钮颜色可能需要处理不同状态下的颜色变化,比如悬停或按下时的效果,否则可能出现颜色不更新的问题。 最后,可能需要查看UE的官方文档或社区资源,确认正确的方法。例如,Slate控件样式设置或者UMG按钮的自定义方法。</think>在UE C++中设置按钮颜色主要通过修改按钮控件样式实现,具体步骤如下: ### 核心方法 1. **获取按钮控件引用** ```cpp UPROPERTY(meta=(BindWidget)) // 需与UMG设计器中变量名一致 class UButton* MyButton; ``` 2. **创建按钮样式结构体** ```cpp FButtonStyle ButtonStyle = FButtonStyle() .SetNormal(FSlateColorBrush(FColor::Red)) // 正常状态 .SetHovered(FSlateColorBrush(FColor::Blue)) // 悬停状态 .SetPressed(FSlateColorBrush(FColor::Green));// 按下状态 ``` 3. **应用样式到按钮** ```cpp if(MyButton){ MyButton->SetStyle(ButtonStyle); MyButton->SetColorAndOpacity(FLinearColor::White); // 叠加透明度 } ``` ### 关键属性说明 - **FSlateColorBrush**:用于定义颜色画刷,支持直接传入$FColor$或$FLinearColor$ - **SetNormal/Hovered/Pressed**:分别对应按钮不同交互状态 - **SetColorAndOpacity**:叠加整体透明度效果[^2] ### 工程实践建议 1. 对于复杂颜色渐变,建议通过UMG设计器创建样式资产 2. 动态颜色修改建议封装成UFUNCTION函数 3. 多状态颜色变化需配合定时器或事件驱动更新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值