IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> UE4使用UMG展示3D物品(C++代码实现) -> 正文阅读

[游戏开发]UE4使用UMG展示3D物品(C++代码实现)

本文所实现的主要流程如下

  1. 创建展示的UMG界面
  2. 动态创建展示的3d模型及旋置到正确的位置
  3. 锁定输入事件,仅在UI层,防止触发关卡逻辑
  4. 监听触控事件,实现旋转及放大事件
  5. 退出,输入事件切换,删除3d模式,关闭界面

分享关键信息小技巧

在正文开始前分享个小技巧,有时候需要发送关键数据给别人时,如账号密码可以借用外部的工具,而不仅仅是在一种聊天软件里面全部发送,1、避免数据在单一层面被截取而导致的数据泄漏,2、防止数据长时间的保存,而被人意外获取。可以在微信里把账号发送给对方,然后密码用分享,文字分享,匿名分享,私密分享 - 问蒙在线工具,用本地加密的方式分享出去,对方只有在有限的时间内且要输入正确的密钥才能得到您的正确信息,有效的避免了通过网络传输而造成的财产损失。

创建UMG的展示界面

在内容浏览器里,右键=>用户界面=>控件蓝图,在这里创建您需的元素,包括(关闭键)。
在根画布面板里选择锚点如下,以保证全屏铺满界面
锚点选择
最终的界面示意图如下
展示的UMG示意图界面布局完了之后,必须在类设置里面关联您的C++类,这里我命名为UExamineDialogUW,然后在该资源上点右键=>复制引用,得到该umg的地址,会得到
/game/dialog/ExamineOnly.ExamineOnly的路径,但是在C++使用必须在结尾添加_C即地址WidgetBlueprint'/game/dialog/ExamineOnly.ExamineOnly_C', 以下是关键c++实现

//加载该蓝图类
UClass* CanvasWidgetClass = LoadClass<UUserWidget>(NULL, TEXT("WidgetBlueprint'/game/dialog/ExamineOnly.ExamineOnly_C'"));
//将该蓝图类实例化
if (auto dialog = CreateWidget<UExamineDialogUW>(GEngine->GameViewport->GetGameInstance(), CanvasWidgetClass)) {
	//添加到视图中
	dialog->AddToViewport(-1);
}

动态创建展示的3D模型。

这里我展示的是蓝图类的Actor模型,所以,我们先创建一个Actor模型
右键=>蓝图类=>Actor,这里,我们在视口里拉入两个静态网格组件,一个命名成SpherePivot这个组件是我们操作的组件,我们不会为其绑定Mesh,另一个做为SpherePivot的子节点,命名为ExamineMesh。
这里拆分成两个节点的原因在于通常美术给的Mesh的起始点都是(0,0,0)我们展示的却是需要围绕着Mesh的中心点做旋转变换,所以在这里创建了SpherePivot做为基准点来做旋转变化。示意图如下:

Actor组件布局中心点为SpherePivot,Actor图同样的,右键复制引用,得到资源地址如Blueprint'/Game/BluePrint/Examine1001.Examine1001',然后我们在C++动态创建这个Actor。是通过SpawnActor创建出来

	UBlueprint* MyWidgetClass = LoadObject<UBlueprint>(NULL, TEXT("Blueprint'/Game/BluePrint/Examine1001.Examine1001'"))
	this->ExamineActor = GetWorld()->SpawnActor<AActor>(MyWidgetClass->GeneratedClass, matix, SpawnParams);

以上代码中用到了一个重要属性matix,这个也是关系到我们能否正常的展示该模型的位置,因为我们无法在umg界面中展示3D模型,实际上该3D模型是添加到关卡中的,所以此时该模型的位置和我们的展示效果相关联。所以此时该值的正确与否和我们展示息息相关。首先我们先获取视口的坐标位置及朝向,然后对该朝向在偏移,最后再把坐标及朝向合成,即得到我们需要的坐标

FVector OutLocation;
FRotator OutRotation;
//获取视口位置及朝向
GetWorld()->GetFirstPlayerController()->GetActorEyesViewPoint(OutLocation, OutRotation);
FVector ExamineOffset(20, 0, 1);
FVector RotatorVector = UKismetMathLibrary::GreaterGreater_VectorRotator(ExamineOffset, OutRotation);
OutLocation += RotatorVector;
auto matix = UKismetMathLibrary::MakeTransform(OutLocation, OutRotation, FVector(1, 1, 1));

此时效果花瓶展示图

禁止关卡层触发INPUT事件

此时展示完成,我们设置只有UI层能接受事件

GetWorld()->GetFirstPlayerController()->SetInputMode(FInputModeUIOnly());

监听触控事件,实现旋转及放大事件

我们在当前类UExamineDialogUW覆写三个函数

virtual FReply NativeOnTouchStarted(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent);
virtual FReply NativeOnTouchMoved(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent);
virtual FReply NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent);
//记录触控点
TMap<int, FVector2D> touchPoints;

InGestureEvent.GetPointerIndex()表示当前为第几个手指,也是多点触控的关键,我们对该值与相应坐标存储要匹配, 我们只会对SpherePivot进行操作,而ExamineMesh是它的子节点,会根据他的变换而自动变化


FReply UExamineDialogUW::NativeOnTouchStarted(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
{
	//记录当前点
	touchPoints.Add(InGestureEvent.GetPointerIndex(), InGestureEvent.GetLastScreenSpacePosition());
	return FReply::Handled();
}

FReply UExamineDialogUW::NativeOnTouchMoved(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
{
	if (!touchPoints.Contains(InGestureEvent.GetPointerIndex()) ) {
		return FReply::Handled();
	}

	if (this->SpherePivot == nullptr) {
		return FReply::Handled();
	}

	FVector2D pre = touchPoints[InGestureEvent.GetPointerIndex()];
	FVector2D now = InGestureEvent.GetLastScreenSpacePosition();
	//如果只有一个点,即表示是旋转
	if (this->touchPoints.Num() == 1) {
		FVector2D offset = now - pre;
		auto rotator = this->SpherePivot->GetRelativeRotation();
		rotator.Yaw += -offset.X / 10;
		rotator.Roll += -offset.Y / 10;
		this->SpherePivot->SetRelativeRotation(rotator);
		touchPoints.Add(InGestureEvent.GetPointerIndex(), InGestureEvent.GetLastScreenSpacePosition());
	}
	//如果有多个点,表示放大缩小
	else {
		auto size1 = this->CalcPointSize();
		touchPoints.Add(InGestureEvent.GetPointerIndex(), InGestureEvent.GetLastScreenSpacePosition());
		auto size2 = this->CalcPointSize();

		float ratio = size2 / size1;
		FVector scale =  this->SpherePivot->GetRelativeScale3D();
		scale *= ratio;
		this->SpherePivot->SetRelativeScale3D(scale);
	}

	return FReply::Handled();
}

FReply UExamineDialogUW::NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
{
//触控结束及时删除点,防止旋转变缩放
	touchPoints.Remove(InGestureEvent.GetPointerIndex());
	return FReply::Handled();
}

float UExamineDialogUW::CalcPointSize()
{
	TArray<FVector2D> array;
	for (auto point : this->touchPoints) {
		array.Push(point.Value);
	}
	if (array.Num() <= 1) {
		return 1;
	}
	return FVector2D::Distance(array[0], array[1]);
}

退出,输入事件切换,删除3d模式,关闭界面

在close事件里,记得把我们的AActor模式相应的删除,然后把输入模式设回游戏和UI的双重的触控模式

	if (this->ExamineActor) {
		this->ExamineActor->Destroy();
		GetWorld()->GetFirstPlayerController()->SetInputMode(FInputModeGameAndUI());
	}

最终效果图如下:
旋转及放大后的效果图
推荐一个在线工具的网站,问蒙在线工具,希望可以帮到你。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:31:04  更:2021-09-26 10:31:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 12:35:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码