实例甜点 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 > ...
随机推荐
- PHP 上传文件大小限制
配置php.ini文件 (以上传500M以下大小的文件为例) 查找以下选项并修改-> file_uploads = On ;打开文件上传选项 upload_max_filesize = 500M ...
- 基于Mac制作iPhone铃声教程,iTunes定制铃声
前言: 网上太多制作方法了,不管是借助第三方软件还是基于iTunes的,不过这些方法都太旧了,有时看起来 ,界面的变化或其他原因,导致很不爽. 正好记录下我最近使用的一种方法: 正文: 一.下载你需要 ...
- Scheme实现二叉查找树及基本操作(添加、删除、并、交)
表转化成平衡二叉树 其中有一种分治的思想. (define (list->tree elements) (define (partial-tree elts n) (if (= n 0) (co ...
- js中的匿名函数自执行
随笔,java中因为有修饰符的存在,那就有private类的存在,js不一样,没有修饰词一说,因此为了防止全局变量的污染,js中就出现了匿名函数,直接上code,看到的人可以自己体会: (functi ...
- websocket多线程问题
title: websocket多线程问题 date: 2017-06-28 11:21:24 categories: websocket tags: [websocket] --- 开发框架 spr ...
- phpstrom识别phalcon框架模板文件的配置
- 在win7下如何设置计划任务每一分钟执行一次
- jQuery从入门到忘记
jQuery 是一套Javascript脚本库,注意 jQuery 是脚本库,而不是脚本框架."库"不等于"框架".jQuery 并不能帮助我们解决脚本的引用管 ...
- 正确、安全地停止SpringBoot应用服务
引言 Spring Boot,作为Spring框架对"约定优先于配置(Convention Over Configuration)"理念的最佳实践的产物,它能帮助我们很快捷的创建出 ...
- Django 踩过的坑(一)
平台:win10 工具:cmd python3 刚刚学习Django搭建环境,网站还木有发布,就直接来了个大麻烦. 一切按着<Django 学习笔记(二)>这篇文章来的,在最后cmd运行服 ...