实例甜点 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 > ...
随机推荐
- Nginx——在Windows环境下安装
下载 Nginx是开源软件,用户可以访问 http://nginx.org/ 网站获取源码包或Windows二进制文件下载.其中1.13.x版本为开发版本,1.12.0版本为稳定版本.开发版本分支会较 ...
- jquery里的attr()方法和prop()方法的区别
在jq的高版本里出现了prop()方法,那么attr()和prop()的区别在哪呢?这两者分别在什么情况用呢? 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. 对于HTML元素我们 ...
- 远程连接mysql 授权方法详解
今在服务器上 有mysql 数据库,远程访问,不想公布root账户,所以,创建了demo账户,允许demo账户在任何地方都能访问mysql数据库中shandong库. 方案一: 在安装mysql的机器 ...
- 生成一个唯一token
$token = md5(uniqid(rand(), true));
- Swift 路由机制设计
设计模式 APP设计模式多种多样,从最初的MVC到MVVM,再到MVP,VIPER等.越来越多的设计模式被开发出来并得以应用,但不论我们用到哪种设计模式,只需要记住高内聚.低耦合那边是好的设计模式.在 ...
- USACO The Castle
首先看一下题目. The CastleIOI'94 - Day 1 In a stroke of luck almost beyond imagination, Farmer John was sen ...
- JavaScript从入门到忘记
JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一.如何编写 二.变 ...
- C# 定时器传值问题详解
//传参数定时器 private static System.Timers.Timer aTimer; Main(ApprovalID); public static void Main(int A ...
- Unity 游戏框架搭建 (六) 关于框架的一些好文和一些思考
在进行项目架构阶段,游戏框架可以解决一部分问题.剩下的架构问题还需要根据不同的项目解决.总之游戏框架是游戏架构的一部分. 关于锤子和钉子: 最近又拿起了<代码大全>和<暗时间 ...
- 拥抱.NET Core系列:依赖注入(2)
上一篇"拥抱.NET Core系列:依赖注入(1)"大体介绍了服务注册.获取和生命周期,这一篇来做一些补充. 由于内容跨度大(.NET Core.ASP.NET Core),所以文 ...