实例甜点 Unreal Engine 4迷你教程(1)之如何用C++将纹理绘制在UserWidget的Image小部件上
完成本迷你教程之前,请前往完成以下迷你教程:
无前置教程待完成。
本教程适合的人群:
初学者,具有开发经验两周;
本示例的目的:为了在代码中实现UMG中的这个功能:

说明:这是一些列迷你教程的首篇,所以步骤比较多。
第1步:创建一个FPS(C++)模板工程,我的工程命名为LearnWidgets
第2步:在c++文件夹中找到以下已有的两个类,LearnWidgetsGameMode派生出BPGM,LearnWidgetsHUD派生出BPHUD;并在BPGM中配置HUD为BPHUD;


第3步:
创建一个继承自AActor的类,称为WidgetMng,表示Widget的管理者类,它的功能将会慢慢变强大。

第4步:
在 工程.build.cs 文件中改动代码:

▼代码开始
public LearnWidgets(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay"
//从这一行开始是新增的——————
, "UMG" }); // Uncomment if you are using Slate UI
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
//新增结束——————
}
▲代码结束
【实验Tips:如果遇到了无法编译的问题,可以尝试关闭Editor,重启VS,后再build】
第5步:
WidgetMng的代码是这样的:(按照我的风格,我会在代码中写入详细的注释,边看代码边看注释就会明白)
▼代码开始
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h"
#include "GameFramework/Actor.h" #include "WidgetMng.generated.h" UCLASS()
class LEARNWIDGETS_API AWidgetMng : public AActor
{
GENERATED_BODY() public:
// Sets default values for this actor's properties
AWidgetMng(); protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override; public:
// Called every frame
virtual void Tick(float DeltaTime) override; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Ws)
TSubclassOf<class UUserWidget> SlaveWidgetClass;
//这是一个UUserWidget的类目(暴露给蓝图以做选择) UPROPERTY()
class UUserWidget* SlaveWidget;
//这是真正的UUserWidget实例的指针(当然起初是null) UFUNCTION()
void Initialize();
//初始化函数 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WsTexture)
UTexture2D* T2D;
//这是一张纹理UTexture2D,暴露给蓝图以做选择 UFUNCTION()
void ChangeImage(UTexture2D* T2D0);
//ChangeImage函数希望将它所管理的SlaveWidget中的Image小部件的图片设置为T2D0纹理 UFUNCTION()
void ChangeText(const FString & F);
//ChangeText函数希望将它所管理的SlaveWidget中的TextBlock小部件的文本设置为F; }; ▲代码结束
以下是cpp文件。 ▼代码开始
// Fill out your copyright notice in the Description page of Project Settings. #include "WidgetMng.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"
#include "Runtime/UMG/Public/Components/Image.h"
#include "Runtime/Engine/Classes/Engine/Texture2D.h"
#include "Runtime/UMG/Public/Components/TextBlock.h"
//这里要加一些头文件,至于头文件如何加,这里就先不解释了。 // Sets default values
AWidgetMng::AWidgetMng()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned
void AWidgetMng::BeginPlay()
{
Super::BeginPlay(); } // Called every frame
void AWidgetMng::Tick(float DeltaTime)
{
Super::Tick(DeltaTime); } void AWidgetMng::Initialize()
{
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("31 Initialize WidgetMng"));
//这是LOG if (SlaveWidgetClass && SlaveWidget==NULL)
{
SlaveWidget = CreateWidget<UUserWidget>(GWorld->GetGameInstance(), SlaveWidgetClass);//【重要】创建UUserWidget的做法
if (SlaveWidget)
{
SlaveWidget->AddToViewport();//将此实例加到屏幕上 }
}
} void AWidgetMng::ChangeImage(UTexture2D* T2D0)
{
UImage* MyImage = Cast<UImage>(SlaveWidget->GetWidgetFromName(TEXT("MyImage")));
//【重要】从SlaveWidget中找到一个名为MyImage的小部件
if (MyImage)
{
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Changing Image With A T2D"));
MyImage->SetBrushFromTexture(T2D0);//【重要】用纹理UTexture2D来设置这个Image小部件
} } void AWidgetMng::ChangeText(const FString & F)
{//【重要】这个函数展示了设置特定文本给一个名为MyTextBlock的小部件;
UTextBlock* MyTextBlock = Cast<UTextBlock>(SlaveWidget->GetWidgetFromName(TEXT("MyTextBlock")));
if (MyTextBlock)
{
MyTextBlock->SetText(FText::FromString(F));
} } ▲代码结束
第5+步:在内容浏览器中新建一个UserWidget(命名为WeaponDisplayer)如下:

注意到它有两个小部件,我们命名为MyImage和MyTextBlock;
第6步:找到WidgetMng(Cpp),然后派生一个蓝图名为BPWidgetMng1,

第7步:给BPWidgetMng1中配置白色框框部分(还记得吗,它们是前面步骤暴露出来的):

注意到这里有一张纹理图片叫wenjiezou,你可以import其它的图像文件进来作为纹理;
第8步:
前面写完了WidgetMng(Widget管理者),现在写HUD的逻辑,希望HUD能够生成WidgetMng;然后再生成UserWidget(也就是SlaveWidget)。(分号后面这句话已经编写完逻辑了,现在要做的就是分号前的那个需求)
在LearnWidgetsHUD中,只需要稍微改改代码即可。
LearnWidgetsHUD.h文件:
▼代码开始
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "WidgetMng/WidgetMng.h"
#include "LearnWidgetsHUD.generated.h" UCLASS()
class ALearnWidgetsHUD : public AHUD
{
GENERATED_BODY() public:
ALearnWidgetsHUD(); /** Primary draw call for the HUD */
virtual void DrawHUD() override; private:
/** Crosshair asset pointer */
class UTexture2D* CrosshairTex; public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WidgetMngs)
TArray<TSubclassOf<AWidgetMng>> WidgetMngsClasses;//【暴露了一些Mngs的类目】
UPROPERTY()
TArray<AWidgetMng*> WidgetMngs;//真正的Mngs实例 virtual void BeginPlay() override;
}; ▲代码结束 LearnWidgetsHUD.cpp文件:
▼代码开始
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #include "LearnWidgetsHUD.h"
#include "Engine/Canvas.h"
#include "Engine/Texture2D.h"
#include "TextureResource.h"
#include "CanvasItem.h"
#include "UObject/ConstructorHelpers.h" ALearnWidgetsHUD::ALearnWidgetsHUD()
{
// Set the crosshair texture
static ConstructorHelpers::FObjectFinder<UTexture2D> CrosshairTexObj(TEXT("/Game/FirstPerson/Textures/FirstPersonCrosshair"));
CrosshairTex = CrosshairTexObj.Object;
} void ALearnWidgetsHUD::DrawHUD()
{
Super::DrawHUD(); // Draw very simple crosshair // find center of the Canvas
const FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.5f); // offset by half the texture's dimensions so that the center of the texture aligns with the center of the Canvas
const FVector2D CrosshairDrawPosition( (Center.X),
(Center.Y + 20.0f)); // draw the crosshair
FCanvasTileItem TileItem( CrosshairDrawPosition, CrosshairTex->Resource, FLinearColor::White);
TileItem.BlendMode = SE_BLEND_Translucent;
Canvas->DrawItem( TileItem );
} //只关注这里,这里实例化了WidgetMng
void ALearnWidgetsHUD::BeginPlay()
{
for (auto index = ; index<WidgetMngsClasses.Num(); index++)
{
AWidgetMng* NewWidgetMng = NewObject<AWidgetMng>(GetGameInstance(), WidgetMngsClasses[index]);
WidgetMngs.Add(NewWidgetMng);
NewWidgetMng->Initialize();
}
} ▲代码结束
第9步:现在再介绍一个点,就是从PC(playercontroller)指挥这个Mng修改文字或图片。我发现没有PC,只有现成的LearnWidgetsCharacter,所以这里就介绍从Character索引到WidgetMng,其实都差不多;
在LearnWidgetsCharacter中加入代码:
void ALearnWidgetsCharacter::Action1()
{
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Action1 ing"));
ALearnWidgetsHUD* HUD = Cast<ALearnWidgetsHUD>(UGameplayStatics::GetPlayerController(this, )->GetHUD());//【重要】这是从Character索引到HUD的方法
if (HUD->WidgetMngs.Num())
{
HUD->WidgetMngs[]->ChangeImage(HUD->WidgetMngs[]->T2D);//【重要】从HUD索引到WidgetMng,调用显示图像函数
}
}
然后再讲这个Action1绑定在Action1输入上(如果这个不懂,请学习setupinputcomponent相关的知识);
第10步:
Gamemode是这样的。(如果你不知道什么是Gamemode,请去官网学习Gamemode内容;)

第11步:

按下Action1后(这个Action1是你自己定义的按键噢):

——小江村儿的文杰 zouwj5@qq.com 2017年8月2日14:56:24
实例甜点 Unreal Engine 4迷你教程(1)之如何用C++将纹理绘制在UserWidget的Image小部件上的更多相关文章
- 实例甜点 Unreal Engine 4迷你教程(2)之用C++改变Image小部件的颜色
完成本迷你教程之前,请前往完成以下迷你教程: ·实例甜点 Unreal Engine 4迷你教程之如何用C++将纹理绘制在UserWidget的Image小部件上: 目标:实现UMG中的此功能: 在上 ...
- 实例甜点 Unreal Engine 4迷你教程(4)之用C++实现添加子Widget到VerticalBox中以及ClearChildren
前置教程: 1. 实例甜点前面的三篇教程: 2. 最好看看笔者前面的一篇关于博文(后记:本来笔者想用C++做DragAndDrop的功能,但是失败了,下面是蓝图实现的方法): http://www.c ...
- 实例甜点 Unreal Engine 4迷你教程(6)之三个重要基础操作SpawnActor、TArray的Add和Remove
本小节的教程需要完成前置教程:建议阅读<实例甜点 Unreal Engine 4迷你教程(5)>,因为5里面提到了本节的工程,不过也可以在不看5的前提下直接阅读本教程. 第一步:Empty ...
- 实例甜点 Unreal Engine 4迷你教程(3)之用C++改变Image小部件的其它属性
完成本迷你教程之前,请前往完成以下迷你教程: ·实例甜点 Unreal Engine 4迷你教程(2)之用C++改变Image小部件的颜色: 在上一次的迷你教程的LearnWidgets工程上进行(如 ...
- 实例甜点 Unreal Engine 4迷你教程(5)之函数中的静态变量
本小节的教程无前置教程,可直接学习,篇幅很短. 本教程浓缩起来就是一句话:函数中的静态变量在调试过程中保留值.所以需要谨慎对待. 什么意思?请先不要一步一步对着做,而整体地看一遍下面的过程: 第一步: ...
- Unreal Engine 4 系列教程 Part 1:入门
原文:Unreal Engine 4 Tutorial for Beginners: Getting Started 作者:Tommy Tran 译者:Shuchang Liu 本篇教程将引导你安装U ...
- Unreal Engine 4 系列教程 Part 3:材质教程
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- Unreal Engine 4 系列教程 Part 4:UI教程
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- Unreal Engine 4 系列教程 Part 5:制作简单游戏
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
随机推荐
- Bash函数
一.什么是Bash函数 Bash不支持goto语句,可以用function实现程序流程跳转.当前shell中一组组织在一起并被命名的命令.比脚本的效率高,一旦定义,就成为shell内存的一部分,可以随 ...
- 超链接访问过后hover样式就不出现的问题是什么?如何解决?
被点击访问过的超链接样式不在具有hover和active了,解决方法是改变CSS属性的排列顺序: L-V-H-A(link,visited,hover,active)
- Java中的事件监听机制
鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...
- VS2017专业版和企业版激活密钥
VS2017专业版和企业版激活密钥 Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q ...
- 【原】无脑操作:eclipse + maven搭建SSM框架
网上看到一些Spring + Spring MVC + MyBatis框架的搭建教程,不是很详细或是时间久远了,自己动手整一个简单无脑的! 0.系统环境 1)Windows 10 企业版 2)JDK ...
- Intellij IDEA查看方法的调用栈
在IDEA中,先双击选定要查看的方法,使用快捷键Ctrl+Alt+h,在右侧就会显示该方法的详细信息,再双击右侧的方法,就定位到方法的代码区.如下图:
- JavaScript深入浅出补充——(一)数据类型,表达式和运算符
项目基本做完,在进行下一阶段学习之前先看视频学习回顾一下JavaScript 一.数据类型 JavaScript中有五种原始类型和一种对象类型 JavaScript弱类型语言中隐式转换 num-0 字 ...
- H5学习第二周
怎么说,在各种感觉中h5学习的第二周已经过来了,先总结一下,感觉学习h5是一件让我爱恨交加的事,学会一些新的知识并把它成功运行出来的时候是非常激动和兴奋的,但是有时候搞不懂一个标签或者属性的时候,就有 ...
- CSS样式之选择器
一.CSS选择器构成 CSS选择器是你想要改变样式的html元素,通俗的说,选择器可以改变html文件中标签的属性,这些属性可以是颜色,背景图,字体等.每个选择器有一条或多条声明,可以同时改变某个标签 ...
- 从栈不平衡问题 理解 calling convention
最近在开发的过程中遇到了几个很诡异的问题,造成了栈不平衡从而导致程序崩溃. 经过几经排查发现是和调用规约(calling convention)相关的问题,特此分享出来. 首先,讲一下什么是调用规约. ...