[UE4]虚幻引擎UE4如何制作可拖动(Drag and Drop)的背包(Scrollbox)(转载)

最终效果

由于隐私保护,不想截实际的效果图,下面给出了示意图,左边是背包A,右边是背包B,将其中的子项目从左侧拖往右侧的背包,然后在插入位置放置。

第一步:

制作一个user widget(在内容浏览器中右键-ui widget-user widget),命名为subwidget_singleitem,这个用作单个物品项目

制作两个user widget,分别作为A和B背包,命名随意。都要向其中声明一个Scrollbox,关于Scrollbox的基本样式设计,可以查看UE4官网,这里不是重点。你可以往Scrollbox里面添加上面的subwidget_singleitem(只需要在palette中键入subwidget_singleitem就可以看到自定义的userwidget),但是这里不这样做。注意是两个背包都这样建立。

 

第二步:初始化一些物品,这些物品(就是上面建立的singleitem)需要有相互辨识度,不然你看不清楚最终的效果是不是合理的。

比如我这里的是生成编号为10到40的物品(注意这里的编号的使用需要自己定义,你应该去了解一下expose-on-spawn的概念,就会知道是怎么做的了)。

这里有一个Scrollbox的语法:Scrollbox->addchild()表示添加单个项目。

背包A和B都这样做,就会有这个效果:

 

就是没有拖动的静态背包。

 

 

第三步【关键】:

在单个项目(subwidget_singleitem)中重载onmousebuttondown事件(下面的截图中由于我已经重载了,所以在列表中看不到):

这个函数表示当鼠标按下(subwidget_singleitem)时触发的事情,内容如下:

Detectdragifpressed表示监测是否有拖动现象(针对鼠标左键),将事件监测结果返回出去。

 

第四步:

在内容浏览器中右键创建蓝图(选择DragAndDrop):

 

双击打开,什么都不用改,只需要改动其中的pivot为centercenter即可:

 

这里表示拖拽时显示的样式将会以centercenter(水平居中和垂直居中于鼠标位置)呈现,效果类似于:

可以看到图标中心位于鼠标处。

当然,我们Windows的拖拽风格不是centercenter,而是mousedown(在鼠标点击处):

 

其它样式你可以自己探索一下,在完成了本教程之后。

 

第五步:

【警告:不要只看图不看字,理解概念很重要!】

在singleitem中重载另一个事件ondragdetected,表示当有拖拽被检测到时,执行如下过程:

 

红色标记处选择你刚刚新建的DragAndDrop。Payload表示过路费,也就是拖拽后拖拽源(也就是A背包,在本例中)将会损失这一个物件(自动得就消逝了,不用做removefromparent的处理)。Defaultdragvisual表示拖动时拖动显示物的样式,也就是黏着在鼠标上的那个图标,这里也是用self(也就是此singleitem本身)。

其它参数先不管,然后返回一个DragAndDropOperation操作出去。

 

第六步:

 

在背包B中重载ondrop事件(如果不记得怎么找重载函数头请翻到前文看看):

 

 

 

这个事件表示当B背包被drop(拖拽的最后一个瞬间,翻译为释放)时调用,这里看到从operation接受到的拖拽操作中,取出payload,然后添加到本地的Scrollbox中(这里的addnewitemat和getfocusindexnow是我自己写的函数)。

难点:由于UE4本身没有实现将物品按照鼠标位置所在处插入,所以需要自己实现!

获得当前屏幕位置-》用“my geometry我的几何”翻译这个物理屏幕位置,得到本地位置(本地位置是指游戏窗口里的本地位置,是一个和窗体大小、和窗体所处物理屏幕的位置无关的一个位置值,是代码内友好的Position)-》用这个本地位置获得鼠标所在处的排列序号(就是我应该插入到哪个序号上),最后四舍五入后添加物品到这个位置上即可(addnewitemat)。

 

第七步(解释getfocusindexnow):

理论解释:

上图中的箭头处就是鼠标最终落脚处。

 

以下列出一个方程组计算排序序列号和当前鼠标位置的关系表达式:

当前鼠标本地位置(Local Position) = 当前鼠标的绝对位置 经过窗体几何的absolute_local转化,即前面提到的:

当前鼠标本地位置 - Scrollbox在帆布上的偏移位置(下图中的红色箭头的长度) = 鼠标相对Scrollbox顶的位置(这个应该很好理解吧!)

鼠标相对Scrollbox顶的位置 + Scrollbox的拉动偏移(拉动偏移是指这个Scrollbox被拉拽了多少) = 鼠标相对Scrollbox的首个物件的理论位置的距离H,即下图中的红色箭头的长度:

 

上述的H值 ÷ 单个singleitem的高度 = 当前鼠标位置的序列号(类型为小数,将其四舍五入即可)

 

最终的getfocusindexnow的表达式为:

 

其中涉及的节点也都在里面可以看到了。

 

第八步(解释):

Addnewitemat在Scrollbox中也没有现成的函数,下图是我的实现,大致的意思是:

这个序列号大于当前的物品数吗,是的话,就直接添加一个child即可。

否的话,就取出Scrollbox中所有的物品,然后insert这个物品(以数组insert的形式实现),清空Scrollbox然后再放置到Scrollbox中。

 

 

 

以上就是完成从A背包拖拽物品到B背包的所有步骤。如果你对其中的操作和函数节点寻找有问题,可以多查查UE4官网上的文档。

转载于:https://www.cnblogs.com/timy/p/9891087.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
虚幻引擎是一款非常强大的游戏引擎,而UnLua则是一种用于虚幻引擎的Lua脚本插件。在实际开发中,我们可能会遇到修改代码后需要重新编译的情况,这样会浪费很多时间。因此,热更新就成为了一个非常实用的功能。 下面是一个详细的示例,展示了如何使用UnLua实现热更新。 1. 安装UnLua插件 首先,我们需要安装UnLua插件。可以在虚幻引擎的插件商店中进行搜索,也可以在GitHub上找到最新的版本。 2. 创建项目 创建一个新的虚幻引擎项目,选择C++模板。在项目设置中启用UnLua插件。 3. 创建脚本 创建一个Lua脚本,例如MyScript.lua。在脚本中编写一个简单的函数: ``` function MyFunction() print("Hello World!") end ``` 4. 编写C++代码 在C++代码中,我们需要执行以下操作: - 加载Lua脚本 - 调用Lua脚本中的函数 - 实现热更新 首先,我们需要在C++代码中加载Lua脚本。可以使用UnLua提供的函数进行加载和执行。在GameMode或Actor的BeginPlay函数中执行以下代码: ``` if (UUnLuaManager::GetInstance()) { UUnLuaManager::GetInstance()->ExecuteFile("MyScript.lua"); } ``` 这将加载并执行MyScript.lua脚本。 接下来,我们需要调用脚本中的函数。可以使用UnLua提供的ExecuteFunction函数。在GameMode或Actor的Tick函数中执行以下代码: ``` if (UUnLuaManager::GetInstance()) { UUnLuaManager::GetInstance()->ExecuteFunction(L, "MyFunction"); } ``` 这将调用MyScript.lua脚本中的MyFunction函数。 现在,我们已经实现了加载Lua脚本和调用函数的功能。但是,如果我们修改了Lua脚本中的代码,我们需要重新编译C++代码才能看到修改后的效果。为了避免这种情况,我们需要实现热更新功能。 在C++代码中,我们可以使用UnLua提供的ReloadFile函数实现热更新。在GameMode或Actor的Tick函数中执行以下代码: ``` if (UUnLuaManager::GetInstance()) { UUnLuaManager::GetInstance()->ReloadFile("MyScript.lua"); } ``` 这将重新加载MyScript.lua脚本,使我们可以在不重新编译C++代码的情况下看到修改后的效果。 至此,我们已经完成了使用UnLua实现热更新的示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值