UE4鼠标悬停,点击效果实现


这个实验做的太艰难了,因为我的电脑已经不太能带的动UE4了,c++代码只要有错误,编译一次要20多分钟。

一、实验要求

目的: 3D Interaction。
要求: 鼠标操作3D空间物体。
必备:悬停高亮
左键拖拽
右键旋转
作品示例↓:
在这里插入图片描述

二、软件核心代码(算法+代码文本)

实现响应用户输入的第一步:首先我们要新建一个自定义的pawn类MyPawn,并设置MyPawn,使之在游戏开始时能自动响应玩家输入。
(Pawn 类提供了一个变量,可供我们在初始化时进行设置,从而为我们处理该内容。)
在这里插入图片描述
添加以下代码到 AMyPawn::AMyPawn 。
在这里插入图片描述
构建基础组件。
在这里插入图片描述
这个变量被标记为 UPROPERTY ,所以可以在 虚幻引擎 中看到它。 这个变量很重要,因为它可以防止游戏启动时或项目或关卡的关闭和重新载入时的变量重置。
在MyPawn类的头文件里面添加:
在这里插入图片描述
在MyPawn类的cpp文件构造函数里面继续添加:
在这里插入图片描述
(这部分代码是按着官方文档写的,它是要做实现玩家移动和右键改变相机视角。
但是相机部分我自己后来没用到,因为我还是做了右键旋转物体而不是相机)

给项目添加操作映射:
在这里插入图片描述
关于动作映射和轴映射,我查了一下具体有啥区别。在代码实现上最大的区别就是动作映射绑定的函数不能带参数,而轴映射需要参数。
在这里插入图片描述
接下来把编译好的MyPawn类创建实例放到世界大纲地图中:
在这里插入图片描述
下面开始依次实现实验要求的基本功能。

1. 鼠标左键拖动实现改变物体位置
前面已经实现了映射绑定,现在我们开始在绑定的函数里添加具体实现。
实现思路:
在点击鼠标左键的绑定函数里记录物体旧的位置:
在这里插入图片描述
在每一帧都会被调用的函数里计算物体新位置并更改:
在这里插入图片描述
接下来在世界大纲视图里选中要进行操作的物体,右键对它的staticmesh进行编辑,在资源编辑器里设置碰撞为复杂碰撞,如下所示:
在这里插入图片描述
完成以上操作后运行,长按鼠标左键就可以拖动物体了。

2.鼠标右键拖动实现物体旋转

首先,先在之前按下鼠标右键绑定的函数startRotate里添加如下所示的代码。与移动鼠标思路一致,获取鼠标的当前位置和物体的当前旋转角度。
在这里插入图片描述
查资料查到FRotator的三个属性,还有yaw,pitch,roll在空间坐标系的作用。
在这里插入图片描述Yaw绕z轴旋转,pitch绕y轴,roll绕x轴旋转。

在这里插入图片描述
观察一下我自己的坐标系,调一下相机的位置,尽可能的让它正一点,比如zoy面正对屏幕,这样后面右键鼠标旋转时,它的旋转效果会好一点。

实现思路:
实现思路跟左键移动类似。
在这里插入图片描述
先写一段代码获得鼠标当前在世界中的位置然后算出每一帧中鼠标的位移量,然后用物体旧的旋转值加上适当处理过的(我这里是直接加上去的,我问了别人,有算线面角再处理的)鼠标位移量,达到新的旋转值。
在这里插入图片描述
我试着调整了一下NewRotation的Yaw,Pich,Roll的值,发现鼠标的右键移动并不能很好的映射(就是它旋转的方向,它旋转的轴是它自己的轴,转是能转了,但效果可能不是你所期望的。)

3.鼠标悬浮实现物体高亮
实现思路:
自己试着按照官网文档新建一个发光的材质,然后把它添加到要变换的物体的staticmesh上。
在这里插入图片描述
然后需要在检测到鼠标悬浮时,切换目标物体材质,检测到鼠标离开时,换回原材质。
接下来在前面用到的碰撞检测函数的代码最前面添加如下代码:
(这段代码的作用是当鼠标离开物体时恢复到物体以前的材质,取消高亮)
在这里插入图片描述
在检测到碰撞物体不为空后,切换物体材质让它变成高亮材质:
桌子的原本材质有两个,所以切换的材质统一使用静态网格体的最后一个材质。
在这里插入图片描述
以上,编译运行即可。

补充一点:需要注意的的是编译运行之前,需要设置鼠标在play界面可见,不然运行的时候就看不到鼠标,把这一段代码添加到BeginPlay()函数里:
在这里插入图片描述

三、游戏运行效果(截图)

效果截图(部分):在这里插入图片描述

四、实验心得

我觉得我快没有办法再用下去了。(绝望.jpg)
只要代码有问题或是代码实现不太好,UE在Vs里编译一次就能花20分钟,在这期间我的浏览器,我挂在电脑上的qq,onenote,连我那个破输入法都变的奇卡无比。
这可能已经不是“有点慢”的概念了。我真的没有办法理解为什么会那么慢,整个人心态都崩溃了。我打算再买个内存条装上看看,如果之后它还是这么慢的话,我都不知道以后工作量再大一点该怎么办,应该会照着教程直接用蓝图做了吧。
这大概就是设备太烂的无能为力吧。

Ue4总体而言过程有点艰难,中文教程太少了。有教程的也全部都是蓝图的教程,代码的教程都是在它的英文论坛上一部分一部分找的。做这个的过程中,也问了走在我前面的人不少问题,在论坛试着找了很多英文教程,目前英语检索能力不太过关,走了不少弯路。

但最后实现出来了,虽然只是最基本的第一页功能,也着实不容易。

惯例,还是记一下在实验过程中遇到的问题。

1.没有与参数列表匹配的 重载函数 “UInputComponent::BindAction” 实例
一直报这个错误,查了好久查不到解决方案,快自闭了。
在这里插入图片描述
后来发现我绑定的几个函数是带参数的,我把参数去掉,就没报这个错了。
在这里插入图片描述
动作映射不能带参数!!!轴映射要带参数。
在这里插入图片描述
2.UE4崩溃
UE4崩溃有两种可能(我遇到的),第一种是代码里面有错误拿去编译运行,有一定几率崩溃。
第二种是代码逻辑错误,比如数组越界,我在实现高亮换材质时遇到了这个。很坑,编译成功,一运行就崩,半天找不到哪错了。
在这里插入图片描述
3.鼠标悬浮(或许以后能用)
最开始想要实现悬浮效果,就试着用下面的代码绑定了文档里的OnBeginCursor还给它绑了自己新写的customOnBeginCursor。试了下效果,可以检测到鼠标悬浮,但是因为换材质要用到的变量挺多,就没有写在customOnBeginCursor里面。
在这里插入图片描述
当鼠标光标移到此组件上并在播放器控制器中启用鼠标悬停事件时调用的事件
在这里插入图片描述
这里面的参数UPrimitiveComponent类官网介绍这个是用于渲染数据,以后应该有机会用到,先码住。
在这里插入图片描述

UE4中,实现鼠标点击任意物体选中效果需要对场景中的所有物体进行遍历,检测每个物体是否被点击。以下是一个简单的实现方法: 1. 在场景中创建一个Actor,并添加一个Box Collision或Sphere Collision组件,用于检测鼠标点击事件。 2. 给这个组件添加OnClicked事件,用于处理鼠标点击事件。 3. 在OnClicked事件处理函数中,使用UE4的Line Trace功能检测鼠标点击的位置是否与场景中的任意物体相交。如果有相交物体,则可以修改其材质或渲染状态来实现选中效果。 以下是一个简单的示例代码: ``` void AMyActor::OnClicked(UPrimitiveComponent* ClickedComp, FKey ButtonPressed) { // 检测鼠标点击位置是否与场景中的物体相交 FVector WorldLocation; FVector WorldDirection; GetWorld()->GetFirstPlayerController()->DeprojectMousePositionToWorld(WorldLocation, WorldDirection); FHitResult HitResult; GetWorld()->LineTraceSingleByChannel(HitResult, WorldLocation, WorldLocation + WorldDirection * 10000.f, ECC_Visibility); // 如果有相交物体,则设置其选中效果 if (HitResult.bBlockingHit) { UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(HitResult.GetComponent()->GetMaterial(0), this); DynamicMaterial->SetVectorParameterValue("Color", FLinearColor::Green); HitResult.GetComponent()->SetMaterial(0, DynamicMaterial); } } ``` 以上代码将在鼠标点击时进行Line Trace检测,如果有相交物体,则将其材质的颜色修改为绿色,从而实现选中效果。需要注意的是,这种方法可能会影响性能,特别是当场景中有大量物体时,因此建议在实际使用时对其进行优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值