实例甜点 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 > ...
随机推荐
- UWP的Converter妙用
MVVM模式的使用,简化了UWP应用的开发,使层次更加分明.在写xaml的时候,有些小技术还是很实用的:比如Converter,字面上理解是转换器,那它到底是转换什么的?接触过的可能知道它起的是类型转 ...
- js实现htmlToWordDemo
之前由于工作需要,需要实现将html内的一部分内容直接转为word和pdf的功能.就研究了一下方法并且实现了两个demo.今天先说一下html to word(才疏学浅,仅供交流,如有错误,请指出). ...
- jq瀑布流代码
<style> #zh{ position:fixed; width:100%; height:100%; background:url(images/bgblack.png); top: ...
- JS面向对象笔记二
菜单导航,<JS面向对象笔记一>, 参考书籍:阮一峰之<JavaScript标准参考教程> 一.构造函数和new命令 二.this关键字 三.构造函数和new命令 四.构造函 ...
- 开源搜索引擎abelkhan
发起一个开源项目http://www.abelkhan.com/ 目前而言,已经用python编写了一个网络爬虫抓取页面,和一个简单的前端 网络爬虫,已经有很多高手写过,我基本上奉行了拿来主义, 得益 ...
- Tornado+MySQL模拟SQL注入
实验环境: python 3.6 + Tornado 4.5 + MySQL 5.7 实验目的: 简单模拟SQL注入,实现非法用户的成功登录 一.搭建环境 1.服务端的tornado主程序app.py ...
- tkinter模块常用参数(python3)
1.使用tkinter.Tk() 生成主窗口(root=tkinter.Tk()):root.title('标题名') 修改框体的名字,也可在创建时使用className参数来命名:root.r ...
- peoplesoft function PSTREENODE 通过 deptid 获得部门树 一级部门 名称
create or replace function ht_gettopdeptNAME(deptid in varchar) return varchar2 is r ); c int; m ); ...
- Memcached在windows下的基本使用
1.Memcached是什么 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动 ...
- Oracle系统表实用操作笔记
1.取得指定用户的所有表名: SQL1: SELECT OWNER AS "对象所有者", OBJECT_NAME AS "表名", OBJECT_ID AS ...