虛幻引擎UE4如何制作可拖動(Drag and Drop)的背包(Scrollbox)


本教程適合初學者(學習經歷已有30天的UE4初學者)。

 

最終效果

由於隱私保護,不想截實際的效果圖,下面給出了示意圖,左邊是背包A,右邊是背包B,將其中的子項目從左側拖往右側的背包,然后在插入位置放置。

第一步:

制作一個user widget(在內容瀏覽器中右鍵-ui widget-user widget),命名為subwidget_singleitem,這個用作單個物品項目

制作兩個user widget,分別作為AB背包,命名隨意。都要向其中聲明一個Scrollbox,關於Scrollbox的基本樣式設計,可以查看UE4官網,這里不是重點。你可以往Scrollbox里面添加上面的subwidget_singleitem(只需要在palette中鍵入subwidget_singleitem就可以看到自定義的userwidget),但是這里不這樣做。注意是兩個背包都這樣建立。

 

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

比如我這里的是生成編號為1040的物品(注意這里的編號的使用需要自己定義,你應該去了解一下expose-on-spawn的概念,就會知道是怎么做的了)。

這里有一個Scrollbox的語法:Scrollbox->addchild()表示添加單個項目。

背包AB都這樣做,就會有這個效果:

 

就是沒有拖動的靜態背包。

 

 

第三步【關鍵】:

在單個項目(subwidget_singleitem)中重載onmousebuttondown事件(下面的截圖中由於我已經重載了,所以在列表中看不到):

這個函數表示當鼠標按下(subwidget_singleitem)時觸發的事情,內容如下:

Detectdragifpressed表示監測是否有拖動現象(針對鼠標左鍵),將事件監測結果返回出去。

 

第四步:

在內容瀏覽器中右鍵創建藍圖(選擇DragAndDrop):

 

雙擊打開,什么都不用改,只需要改動其中的pivotcentercenter即可

 

這里表示拖拽時顯示的樣式將會以centercenter(水平居中和垂直居中於鼠標位置)呈現,效果類似於:

可以看到圖標中心位於鼠標處。

當然,我們Windows的拖拽風格不是centercenter,而是mousedown(在鼠標點擊處):

 

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

 

第五步:

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

singleitem中重載另一個事件ondragdetected,表示當有拖拽被檢測到時,執行如下過程:

 

紅色標記處選擇你剛剛新建的DragAndDropPayload表示過路費,也就是拖拽后拖拽源(也就是A背包,在本例中)將會損失這一個物件(自動得就消逝了,不用做removefromparent的處理)。Defaultdragvisual表示拖動時拖動顯示物的樣式,也就是黏着在鼠標上的那個圖標,這里也是用self(也就是此singleitem本身)。

其它參數先不管,然后返回一個DragAndDropOperation操作出去。

 

第六步:

 

在背包B中重載ondrop事件(如果不記得怎么找重載函數頭請翻到前文看看):

 

 

 

這個事件表示當B背包被drop(拖拽的最后一個瞬間,翻譯為釋放)時調用,這里看到從operation接受到的拖拽操作中,取出payload,然后添加到本地的Scrollbox中(這里的addnewitematgetfocusindexnow是我自己寫的函數)。

難點:由於UE4本身沒有實現將物品按照鼠標位置所在處插入,所以需要自己實現!

獲得當前屏幕位置-》用“my geometry我的幾何”翻譯這個物理屏幕位置,得到本地位置(本地位置是指游戲窗口里的本地位置,是一個和窗體大小、和窗體所處物理屏幕的位置無關的一個位置值,是代碼內友好的Position-》用這個本地位置獲得鼠標所在處的排列序號(就是我應該插入到哪個序號上),最后四舍五入后添加物品到這個位置上即可(addnewitemat)。

 

第七步(解釋getfocusindexnow):

理論解釋:

上圖中的箭頭處就是鼠標最終落腳處。

 

以下列出一個方程組計算排序序列號和當前鼠標位置的關系表達式:

當前鼠標本地位置(Local Position= 當前鼠標的絕對位置 經過窗體幾何的absolute_local轉化,即前面提到的:

當前鼠標本地位置 - Scrollbox在帆布上的偏移位置(下圖中的紅色箭頭的長度) = 鼠標相對Scrollbox頂的位置(這個應該很好理解吧!)

鼠標相對Scrollbox頂的位置 + Scrollbox的拉動偏移(拉動偏移是指這個Scrollbox被拉拽了多少) = 鼠標相對Scrollbox的首個物件的理論位置的距離H,即下圖中的紅色箭頭的長度:

 

上述的H值 ÷ 單個singleitem的高度 = 當前鼠標位置的序列號(類型為小數,將其四舍五入即可)

 

最終的getfocusindexnow的表達式為:

 

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

 

第八步(解釋):

AddnewitematScrollbox中也沒有現成的函數,下圖是我的實現,大致的意思是:

這個序列號大於當前的物品數嗎,是的話,就直接添加一個child即可。

否的話,就取出Scrollbox中所有的物品,然后insert這個物品(以數組insert的形式實現),清空Scrollbox然后再放置到Scrollbox中。

 

 

 

以上就是完成從A背包拖拽物品到B背包的所有步驟。如果你對其中的操作和函數節點尋找有問題,可以多查查UE4官網上的文檔。

 

 

——20177810:58:01 小江村兒的文傑

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM