Skip to content
UI Drag and Drop Events

UI Drag and Drop Events

It takes about 15 minutes to read this article

This document shows you how to make a drag-and-drop UI, which is commonly used for dragging and dropping items within a achieve bag

onDragDetected(InGemotry :Geometry,InPointerEvent:PointerEvent) : DragDropOperation

  • When a drag is triggered, a generated drag event is returned
  • InGeometry: Geometry can be used to get coordinate information for the UI
  • InPointerEvent: A PointerEvent can be used to get mouse click or swipe information
  • Note that you need to call detectDrag(dragKey: Keys): EventReply or detectDragIfPressed(inPointEvent: PointerEvent, dragKey: Keys): EventReply, which means that the onDragDetected event can be triggered before the drag operation can be detected
  • Use newDragDrop(inVisualWidget: Widget, inTag?: string, inPayLoad?: any, inPivot?: DragPivot, inOffset?: Vector2): DragDropOperation to return a new drag event
    • inVisualWidget: Widget passes in the UI that the generated drag event displays when dragging, note that the UI content used for display will be destroyed later, so it is best to use the new temporary UI here
    • inTag?: string The tag text of the dragged event that is generate
    • inPayLoad?: Any Drag event data information is passed
    • inPivot?: DragPivot passes in the anchor point of the drag display UI
    • inOffset?: The Vector2 incoming drag shows the percentage of UI offset relative to the anchor point, which is determined by both inPivot and inOffsetmouse click or swipe is the relative position of this display UI

Example:

ts
/**
     * When this UI interface is available to receive events
     * Triggered when the finger or mouse triggers a touch
     * Returns whether the event was processed
     * If it is processed, then this UI interface can receive subsequent Move and End events for this Touch
     * If it is not processed, then this UI interface will not be able to receive subsequent Move and End events for this Touch
     */
    onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
      /**
     * Triggered once when detectDrag/detectDragIfPressed is called on the UI interface
     * Can trigger the start of a drag event to generate
     * Returns a generated drag event newDragDrop can generate an event once
     */
    protected onDragDetected(InGemotry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
        let ui=createUIByName("NewUI")
        return this.newDragDrop(ui,"DragDropTag",null,DragPivot.CenterCenter,Vector2.zero);
    }
/**
     * When this UI interface is available to receive events
     * Triggered when the finger or mouse triggers a touch
     * Returns whether the event was processed
     * If it is processed, then this UI interface can receive subsequent Move and End events for this Touch
     * If it is not processed, then this UI interface will not be able to receive subsequent Move and End events for this Touch
     */
    onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
      /**
     * Triggered once when detectDrag/detectDragIfPressed is called on the UI interface
     * Can trigger the start of a drag event to generate
     * Returns a generated drag event newDragDrop can generate an event once
     */
    protected onDragDetected(InGemotry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
        let ui=createUIByName("NewUI")
        return this.newDragDrop(ui,"DragDropTag",null,DragPivot.CenterCenter,Vector2.zero);
    }

onDrop(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation) : boolean

  • The drag event is triggered when the UI is released, and returns true to indicate that the event is processed; Here you can write the logic that you want to trigger when you release the UI
  • The UI displayed by the drag and drop event will be automatically destroyed, and if you still want to display this UI, you need to create it again

Example:

ts
/**
     * The drag and drop operation generates an event when this UI releases is completed after the event is triggered
     * If it returns true, it means that the event has been processed, and the event will not continue to bubble up to the UI at the next level of this UI
     */
    protected onDrop(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation):boolean {
        let UI1=createUIByName("NewUI")
        this.uiWidgetBase.rootContent.addChild(UI1)
        UI1.position=(new Vector2(absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).x-UI1.size.x*0.5,absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).y-UI1.size.y*0.5))
        return true;
    }
/**
     * The drag and drop operation generates an event when this UI releases is completed after the event is triggered
     * If it returns true, it means that the event has been processed, and the event will not continue to bubble up to the UI at the next level of this UI
     */
    protected onDrop(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation):boolean {
        let UI1=createUIByName("NewUI")
        this.uiWidgetBase.rootContent.addChild(UI1)
        UI1.position=(new Vector2(absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).x-UI1.size.x*0.5,absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).y-UI1.size.y*0.5))
        return true;
    }

onDragEnter(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation) : void

  • Triggers when a UI being dragged comes within the range of the UI

Example:

ts
/**
     * The drag-and-drop operation generate triggered when entering this UI after the event is triggered
     */
    protected onDragEnter(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation) {
        console.warn("onDragEnter"+InDragDropEvent.screenSpacePosition)
    }
/**
     * The drag-and-drop operation generate triggered when entering this UI after the event is triggered
     */
    protected onDragEnter(InGemotry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation) {
        console.warn("onDragEnter"+InDragDropEvent.screenSpacePosition)
    }

onDragLeave(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) : void

  • Triggers when a dragged UI leaves the range of the UI

Example:

ts
/**
     * The drag and drop action generate triggered when you leave the UI after the event is triggered
     */
    protected onDragLeave(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) {
        console.warn("onDragLeave"+InDragDropEvent.screenSpacePosition)
    }
/**
     * The drag and drop action generate triggered when you leave the UI after the event is triggered
     */
    protected onDragLeave(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) {
        console.warn("onDragLeave"+InDragDropEvent.screenSpacePosition)
    }

onDragCancelled(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) : void

  • The drag event is not completed but is canceled
  • If the onDrop event is not triggered when it is released, onDragCancelled will be triggered; You can also use the function cancelDragDrop/endDragDrop to cancel the drag event

Example:

ts
/**
     * After the drag and drop operation is triggered by the generated event, the drag event is not completed but is canceled
     */
    protected onDragCancelled(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) {
        console.warn("onDragCancelled")
    }
/**
     * After the drag and drop operation is triggered by the generated event, the drag event is not completed but is canceled
     */
    protected onDragCancelled(InDragDropEvent:PointerEvent,InDragDropOperation : DragDropOperation) {
        console.warn("onDragCancelled")
    }

onDragOver(InGeometry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation):boolean

  • When a dragged UI passes within the range of the UI, it returns true to indicate that the event has been processed

Example:

ts
/**
     * The drag-and-drop action generate triggered when the event passes through this UI
     * If it returns true, it means that the event has been processed, and the event will not continue to bubble up to the UI at the next level of this UI
     */
    protected onDragOver(InGeometry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation):boolean {
        console.warn("onDragOver"+InDragDropEvent.screenSpacePosition)
        return true;
    }
/**
     * The drag-and-drop action generate triggered when the event passes through this UI
     * If it returns true, it means that the event has been processed, and the event will not continue to bubble up to the UI at the next level of this UI
     */
    protected onDragOver(InGeometry :Geometry,InDragDropEvent:PointerEvent,InDragDropOperation:DragDropOperation):boolean {
        console.warn("onDragOver"+InDragDropEvent.screenSpacePosition)
        return true;
    }
  • The detectDrag/detectDragIfPressed function in the UIBehavior class is used to start detecting whether there is a drag operation
  • The newDragDrop function of the UIBehavior class is used to create a new drag event
    • These three functions have been described in the onDragDetected section above

Example:

ts
class UIBehavior {
        /**
         * @description The detect that triggers the DragDrop event
         * @effect Effective when called on client-side.
         * @param dragKey usage: trigger key default:Keys
         * @returns Returns the triggered event reply
         */
        detectDrag(dragKey: Keys): EventReply;
        /**
         * @description If the event detect passed, a reply to the DragDrop event will be triggered
         * @effect Effective when called on client-side.
         * @param inPointEvent usage: Pass the event information that was triggered
         * @param dragKey usage: Trigger key
         * @returns Returns the triggered event reply
         */
        detectDragIfPressed(inPointEvent: PointerEvent, dragKey: Keys): EventReply;
        /**
         * @description create DragDrop event
         * @effect Effective when called on client-side.
         * @param inVisualWidget usage: Drag and drop the displayed UI widget
         * @param inTag usage:tag text default:""
         * @param inPayLoad usage: drag and drop event data information default: null
         * @param inPivot usage: Drag and drop the display UI's anchor default:UIDragPivot.TopLeft
         * @param inOffset usage: Drag and drop the percentage of the UI relative to the offset of the anchor default:vector2(0,0)
         * @returns Returns the triggered event reply
         */
        newDragDrop(inVisualWidget: Widget, inTag?: string, inPayLoad?: any, inPivot?: DragPivot, inOffset?: Vector2): DragDropOperation;
    }
class UIBehavior {
        /**
         * @description The detect that triggers the DragDrop event
         * @effect Effective when called on client-side.
         * @param dragKey usage: trigger key default:Keys
         * @returns Returns the triggered event reply
         */
        detectDrag(dragKey: Keys): EventReply;
        /**
         * @description If the event detect passed, a reply to the DragDrop event will be triggered
         * @effect Effective when called on client-side.
         * @param inPointEvent usage: Pass the event information that was triggered
         * @param dragKey usage: Trigger key
         * @returns Returns the triggered event reply
         */
        detectDragIfPressed(inPointEvent: PointerEvent, dragKey: Keys): EventReply;
        /**
         * @description create DragDrop event
         * @effect Effective when called on client-side.
         * @param inVisualWidget usage: Drag and drop the displayed UI widget
         * @param inTag usage:tag text default:""
         * @param inPayLoad usage: drag and drop event data information default: null
         * @param inPivot usage: Drag and drop the display UI's anchor default:UIDragPivot.TopLeft
         * @param inOffset usage: Drag and drop the percentage of the UI relative to the offset of the anchor default:vector2(0,0)
         * @returns Returns the triggered event reply
         */
        newDragDrop(inVisualWidget: Widget, inTag?: string, inPayLoad?: any, inPivot?: DragPivot, inOffset?: Vector2): DragDropOperation;
    }
  • There are also drag-and-drop event-related functions that can be used to interrupt/get/judge the current drag-and-drop event
ts
declare namespace UI {
        /**
         * @description Interrupt a drag event and pass in an action event
         * @effect Effective when called on client-side.
         * @param InReply usage: Event
         */
        function endDragDrop(InReply: EventReply): void;
        /**
         * @description Interrupt all DragDrops
         * @effect Effective when called on client-side.
         */
        function cancelDragDrop(): void;
        /**
         * @description Determine whether there is a DragDrop event
         * @effect Effective when called on client-side.
         * @returns boolean
         */
        function isDragDropping(): boolean;
        /**
         * @description Get the current DragDrop event
         * @effect Effective when called on client-side.
         * @returns Returns the current DragDrop event
         */
        function getDragDroppingContent(): DragDropOperation;
    }
declare namespace UI {
        /**
         * @description Interrupt a drag event and pass in an action event
         * @effect Effective when called on client-side.
         * @param InReply usage: Event
         */
        function endDragDrop(InReply: EventReply): void;
        /**
         * @description Interrupt all DragDrops
         * @effect Effective when called on client-side.
         */
        function cancelDragDrop(): void;
        /**
         * @description Determine whether there is a DragDrop event
         * @effect Effective when called on client-side.
         * @returns boolean
         */
        function isDragDropping(): boolean;
        /**
         * @description Get the current DragDrop event
         * @effect Effective when called on client-side.
         * @returns Returns the current DragDrop event
         */
        function getDragDroppingContent(): DragDropOperation;
    }
ts
class DragDropOperation {
        /**
         * @description Judge whether it is the same
         * @effect Effective when called on client-side.
         * @param other usage: Another UI drag event
         * @returns boolean
         */
        equal(other: DragDropOperation): boolean;
        /**
         * @description Get the Tag tag
         * @effect Effective when called on client-side.
         * @returns Returns the tag
         */
        getTag(): string;
        /**
         * @description Get the UI displayed by dragging and dropping
         * @effect Effective when called on client-side.
         * @returns Drag and drop the displayed UI
         */
        getDragVisualWidget(): Widget;
        /**
         * @description Get the drag and drop anchor
         * @effect Effective when called on client-side.
         * @returns Drag and drop anchor
         */
        getDragPivot(): DragPivot;
        /**
         * @description Get the percentage offset of the drag and drop UI
         * @effect Effective when called on client-side.
         * @returns Percentage offset
         */
        getOffset(): Vector2;
        /**
         * @description Get the data information passed
         * @effect Effective when called on client-side.
         * @returns Data information
         */
        tryGetDragDropPayLoad(): DragDropPayLoad;
        /**
         * @description Get the data information passed
         * @effect Effective when called on client-side.
         * @returns Data information
         */
        tryGetDragDropPayLoadAs<T extends DragDropPayLoad>(): T;
    }
class DragDropOperation {
        /**
         * @description Judge whether it is the same
         * @effect Effective when called on client-side.
         * @param other usage: Another UI drag event
         * @returns boolean
         */
        equal(other: DragDropOperation): boolean;
        /**
         * @description Get the Tag tag
         * @effect Effective when called on client-side.
         * @returns Returns the tag
         */
        getTag(): string;
        /**
         * @description Get the UI displayed by dragging and dropping
         * @effect Effective when called on client-side.
         * @returns Drag and drop the displayed UI
         */
        getDragVisualWidget(): Widget;
        /**
         * @description Get the drag and drop anchor
         * @effect Effective when called on client-side.
         * @returns Drag and drop anchor
         */
        getDragPivot(): DragPivot;
        /**
         * @description Get the percentage offset of the drag and drop UI
         * @effect Effective when called on client-side.
         * @returns Percentage offset
         */
        getOffset(): Vector2;
        /**
         * @description Get the data information passed
         * @effect Effective when called on client-side.
         * @returns Data information
         */
        tryGetDragDropPayLoad(): DragDropPayLoad;
        /**
         * @description Get the data information passed
         * @effect Effective when called on client-side.
         * @returns Data information
         */
        tryGetDragDropPayLoadAs<T extends DragDropPayLoad>(): T;
    }

Example 1: Make the simplest draggable image

  • step.1Create a new NewUI file and put the draggable UI content in this UI file as a customized UI widget, and then write itScripts
  • In this example, we want to drag a blank image
  • Note that the align of the root should be set to the top left aligned and the visibility of the image should be set to visible

TypeScript
import NewUI_generate from "./ui-generate/NewUI_generate";

Creates a TestDragDropPayLoad class that inherits DragDropPayLoad, passes the newDragDrop function as a parameter payLoad, and passes some along with the drag eventInformation
export class TestDragDropPayLoad extends DragDropPayLoad {

    private test1 : UserWidget ;
    public get Test1() {
        return this.test1;
    }
    public set Test1(v :UserWidget) {
         this.test1 = v;
    }
}

export default class NewUIScript extends NewUI_generate {
	/** 
	 * After the UI file is successfully constructed, initialize it first at the right time 
	 */
	protected onStart() {
		Specifies whether onUpdate can be triggered every frame
		this.canUpdate = false;
		this.layer = UILayerMiddle;
		console.log("________");
	}

    When the Player touches this UI, it starts to detect if a drag operation has occurred
	onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        console.log("OnTouch"+InPointerEvent.screenSpacePosition)
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
    When the Player touches this UI, it starts to detect if a drag operation has occurred
    onTouchEnded(InGemetry: Geometry, InPointEvent: PointerEvent): EventReply {
        return EventReply.handled;
    }
        When the drag operation is detected, a new drag and drop event is created, and the display UI, tag, data information, and Anchor points and offsets
	protected onDragDetected(InGeometry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
		console.log("OnDrag"+InPointerEvent.screenSpacePosition)
		let ui=createUIByName("NewUI")

		The information we pass with the payLoad parameter here is this UI object for ease of use in onDropCreate a new UI object and destroy the old one
		const payLoad = new TestDragDropPayLoad();
        payLoad.Test1=this.uiWidgetBase
        return this.newDragDrop(ui, "DragDropTag", payLoad, DragPivot.CenterCenter, new Vector2(0,0));	
	}
import NewUI_generate from "./ui-generate/NewUI_generate";

Creates a TestDragDropPayLoad class that inherits DragDropPayLoad, passes the newDragDrop function as a parameter payLoad, and passes some along with the drag eventInformation
export class TestDragDropPayLoad extends DragDropPayLoad {

    private test1 : UserWidget ;
    public get Test1() {
        return this.test1;
    }
    public set Test1(v :UserWidget) {
         this.test1 = v;
    }
}

export default class NewUIScript extends NewUI_generate {
	/** 
	 * After the UI file is successfully constructed, initialize it first at the right time 
	 */
	protected onStart() {
		Specifies whether onUpdate can be triggered every frame
		this.canUpdate = false;
		this.layer = UILayerMiddle;
		console.log("________");
	}

    When the Player touches this UI, it starts to detect if a drag operation has occurred
	onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        console.log("OnTouch"+InPointerEvent.screenSpacePosition)
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
    When the Player touches this UI, it starts to detect if a drag operation has occurred
    onTouchEnded(InGemetry: Geometry, InPointEvent: PointerEvent): EventReply {
        return EventReply.handled;
    }
        When the drag operation is detected, a new drag and drop event is created, and the display UI, tag, data information, and Anchor points and offsets
	protected onDragDetected(InGeometry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
		console.log("OnDrag"+InPointerEvent.screenSpacePosition)
		let ui=createUIByName("NewUI")

		The information we pass with the payLoad parameter here is this UI object for ease of use in onDropCreate a new UI object and destroy the old one
		const payLoad = new TestDragDropPayLoad();
        payLoad.Test1=this.uiWidgetBase
        return this.newDragDrop(ui, "DragDropTag", payLoad, DragPivot.CenterCenter, new Vector2(0,0));	
	}
  • step.2It is then written in the UI script of another UI file that is released by the listener (in this case, the DefaultUI file is used directly). the logic of releasing;
  • In this example, we don't need to specify the logic that releases the triggers on a certain UI, but rather we want to listen to the blank image throughout the screenrelease, re-create a new blank in the position of the releaseimage and destroy the old blank image, so you can write an onDrop event in the UI script of the DefaultUI file of the newly created project
TypeScript
import {TestDragDropPayLoad} from "./NewUIScript";
import DefaultUI_generate from "./ui-generate/DefaultUI_generate";

@UIBind('')
export default class UIDefault extends DefaultUI_generate {

	/** Calling ONLY ONCE DURING EXPERIENCES FOR NON-TEMPLATE INSTANCES */
    protected onStart() {
	}

    /**
     * Drag and drop event completed
     */
    onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.warn("OnDrop"+InDragDropEvent.screenSpacePosition)
		Re create a blank image customize UI and set the position
		let ui1=createUIByName("NewUI")
		this.uiWidgetBase.rootContent.addChild(ui1)
		ui1.position=(new Vector2(absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).x-ui1.size.x*0.5,absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).y-ui1.size.y*0.5))
		console.log(ui1.position);
		Destroy the old blank image UI
		const payLoad = InOperation.tryGetDragDropPayLoadAs<TestDragDropPayLoad>();
		const test1 = payLoad.Test1;
		test1.destroyObject()
    }

	    /**
     * After the drag and drop operation is triggered by the generated event, it is triggered when the drag and drop event is canceled without completing the completion
     */
    protected onDragCancelled(InGemotry :Geometry,InDragDropEvent:PointerEvent) {
		console.warn("onDragCancelled"+InDragDropEvent.screenSpacePosition)
    }
}
import {TestDragDropPayLoad} from "./NewUIScript";
import DefaultUI_generate from "./ui-generate/DefaultUI_generate";

@UIBind('')
export default class UIDefault extends DefaultUI_generate {

	/** Calling ONLY ONCE DURING EXPERIENCES FOR NON-TEMPLATE INSTANCES */
    protected onStart() {
	}

    /**
     * Drag and drop event completed
     */
    onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.warn("OnDrop"+InDragDropEvent.screenSpacePosition)
		Re create a blank image customize UI and set the position
		let ui1=createUIByName("NewUI")
		this.uiWidgetBase.rootContent.addChild(ui1)
		ui1.position=(new Vector2(absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).x-ui1.size.x*0.5,absoluteToLocal(InGemotry,InDragDropEvent.screenSpacePosition).y-ui1.size.y*0.5))
		console.log(ui1.position);
		Destroy the old blank image UI
		const payLoad = InOperation.tryGetDragDropPayLoadAs<TestDragDropPayLoad>();
		const test1 = payLoad.Test1;
		test1.destroyObject()
    }

	    /**
     * After the drag and drop operation is triggered by the generated event, it is triggered when the drag and drop event is canceled without completing the completion
     */
    protected onDragCancelled(InGemotry :Geometry,InDragDropEvent:PointerEvent) {
		console.warn("onDragCancelled"+InDragDropEvent.screenSpacePosition)
    }
}
  • step.3Finally, we drag the customized UI widget (the NewUI file) of the blank image into DefaultUI file; You can also use the dynamic create method, and then run the experience, and we have a change position that can be dragged and dropped freely a blank image

Example 2: Make a bag panel with a drag-and-drop function

  • step.1Create a new BagItem file and put the UI content that allows dragging, as a customized UI widget in this UI file
  • Here we hang all UI content under a self-built Container, so that it is easy to directly swap the entire Container when dragging two grids to swap positions
  • Each slot must be allowed to be dragged and dropped, as in the previous example, use the onDragDetected event to create a new UI drag event
  • There needs to be a function to achieve the ability to exchange positions between two cells when other cells are dragged onto this grid, and this part of the logic is written in the onDrop event
  • You also need to make an effect of dragging out the bag panel and dropping the item release, and this part of the logic is written in the onDropCancelled event
  • Note that the align of the root should be set to the top left aligned and the visibility of the image should be set to visible

TypeScript
import BagItem_generate from "./ui-generate/BagItem_generate";
Creates a TestDragDropPayLoad class that inherits DragDropPayLoad, passes the newDragDrop function as a parameter payLoad, and passes some along with the drag eventInformation
export class TestDragDropPayLoad extends DragDropPayLoad {

    private test1 : UserWidget ;
    public get Test1() {
        return this.test1;
    }
    public set Test1(v :UserWidget) {
         this.test1 = v;
    }
}

export default class BagItem extends BagItem_generate {
	imageColor:LinearColor
	/** 
	 * After the UI file is successfully constructed, initialize it first at the right time 
	 */
	protected onStart() {
		Each tile is create with a random change image color, and here we are simulating that each tile is a different item
		this.imageColor= new LinearColor(Math.random(),Math.random(),Math.random(),1.0)
		this.icon.imageColor= this.imageColor
	}


	onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        console.log("onTouchStarted"+InPointerEvent.screenSpacePosition)
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
	onTouchEnded(InGemotry: Geometry, InPointerEvent: PointerEvent): EventReply {
		console.log("onTouchEnded"+InPointerEvent.screenSpacePosition)
        return EventReply.handled;
    }
	onDragDetected(InGeometry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
		console.log("onDragDetected"+InPointerEvent.screenSpacePosition)
		let uiiconnow=this.uiWidgetBase.findChildByPath('RootCanvas/canvas/icon') as Image
		this.imageColor=uiiconnow.imageColor
		let uidrag=createUIByName("BagItem")
		let uiicon=uidrag.findChildByPath('RootCanvas/canvas/icon') as Image
		uiicon.imageColor= this.imageColor
		const payLoad = new TestDragDropPayLoad();
        payLoad.Test1=this.uiWidgetBase
        return this.newDragDrop(uidrag, "DragDropTag", payLoad, DragPivot.CenterCenter, Vector2.zero);	
	}
    
	After dragging out the scope of each item, it is released, consuming the UI and simulating the effect of discarding
	onDragCancelled(InGemotry :Geometry,InDragDropEvent:PointerEvent) {
		this.uiWidgetBase.destroyObject()
		console.log("onDragCancelled")
	}
	
	After the other item completes the onDrop event on this item, the two parties exchange UI
	onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.log("OnDrop"+InDragDropEvent.screenSpacePosition)
		const payLoad = InOperation.tryGetDragDropPayLoadAs<TestDragDropPayLoad>();
		const test1 = payLoad.Test1;
		let uiexchange=test1.rootContent.getChildAt(0) as Widget
		test1.rootContent.addChild(this.rootCanvas.getChildAt(0))
		this.rootCanvas.addChild(uiexchange)
		console.log(test1.parent);
		return true
    }
}
import BagItem_generate from "./ui-generate/BagItem_generate";
Creates a TestDragDropPayLoad class that inherits DragDropPayLoad, passes the newDragDrop function as a parameter payLoad, and passes some along with the drag eventInformation
export class TestDragDropPayLoad extends DragDropPayLoad {

    private test1 : UserWidget ;
    public get Test1() {
        return this.test1;
    }
    public set Test1(v :UserWidget) {
         this.test1 = v;
    }
}

export default class BagItem extends BagItem_generate {
	imageColor:LinearColor
	/** 
	 * After the UI file is successfully constructed, initialize it first at the right time 
	 */
	protected onStart() {
		Each tile is create with a random change image color, and here we are simulating that each tile is a different item
		this.imageColor= new LinearColor(Math.random(),Math.random(),Math.random(),1.0)
		this.icon.imageColor= this.imageColor
	}


	onTouchStarted(InGeometry :Geometry,InPointerEvent:PointerEvent) :EventReply{
        console.log("onTouchStarted"+InPointerEvent.screenSpacePosition)
        return this.detectDragIfPressed(InPointerEvent, Keys.AnyKey)
    }
	onTouchEnded(InGemotry: Geometry, InPointerEvent: PointerEvent): EventReply {
		console.log("onTouchEnded"+InPointerEvent.screenSpacePosition)
        return EventReply.handled;
    }
	onDragDetected(InGeometry :Geometry,InPointerEvent:PointerEvent):DragDropOperation {
		console.log("onDragDetected"+InPointerEvent.screenSpacePosition)
		let uiiconnow=this.uiWidgetBase.findChildByPath('RootCanvas/canvas/icon') as Image
		this.imageColor=uiiconnow.imageColor
		let uidrag=createUIByName("BagItem")
		let uiicon=uidrag.findChildByPath('RootCanvas/canvas/icon') as Image
		uiicon.imageColor= this.imageColor
		const payLoad = new TestDragDropPayLoad();
        payLoad.Test1=this.uiWidgetBase
        return this.newDragDrop(uidrag, "DragDropTag", payLoad, DragPivot.CenterCenter, Vector2.zero);	
	}
    
	After dragging out the scope of each item, it is released, consuming the UI and simulating the effect of discarding
	onDragCancelled(InGemotry :Geometry,InDragDropEvent:PointerEvent) {
		this.uiWidgetBase.destroyObject()
		console.log("onDragCancelled")
	}
	
	After the other item completes the onDrop event on this item, the two parties exchange UI
	onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.log("OnDrop"+InDragDropEvent.screenSpacePosition)
		const payLoad = InOperation.tryGetDragDropPayLoadAs<TestDragDropPayLoad>();
		const test1 = payLoad.Test1;
		let uiexchange=test1.rootContent.getChildAt(0) as Widget
		test1.rootContent.addChild(this.rootCanvas.getChildAt(0))
		this.rootCanvas.addChild(uiexchange)
		console.log(test1.parent);
		return true
    }
}
  • step.2Make a simple bag panel and write the logic manually add item slots
  • Container in the bag panel need to turn on the automatic layout and mesh layoutfunction, so that dynamically added grids are automatically arranged; More information about Container features can be found in the product manualUI Widget - Container
TypeScript
@UIBind('')
export default class UIDefault extends UIScript {
    Character: Character;

	/** Calling ONLY ONCE DURING EXPERIENCES FOR NON-TEMPLATE INSTANCES */
    protected onStart() { 
		Specifies whether onUpdate can be triggered every frame
		this.canUpdate = false;

		Locate the corresponding button and container
		const newBtn = this.uiWidgetBase.findChildByPath('RootCanvas/StaleButton') as StaleButton
		const canvas = this.uiWidgetBase.findChildByPath('RootCanvas/Canvas') as Canvas

		click button, create UI
		newBtn.onPressed.add(()=>{
			create customize the UI component and mount it to the Container
			let item= createUIByName('BagItem.ui') as UserWidget
			canvas.addChild(item)
		})	
    }

	onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.log("OnDrop"+InDragDropEvent.screenSpacePosition)
		return true
    }
}
@UIBind('')
export default class UIDefault extends UIScript {
    Character: Character;

	/** Calling ONLY ONCE DURING EXPERIENCES FOR NON-TEMPLATE INSTANCES */
    protected onStart() { 
		Specifies whether onUpdate can be triggered every frame
		this.canUpdate = false;

		Locate the corresponding button and container
		const newBtn = this.uiWidgetBase.findChildByPath('RootCanvas/StaleButton') as StaleButton
		const canvas = this.uiWidgetBase.findChildByPath('RootCanvas/Canvas') as Canvas

		click button, create UI
		newBtn.onPressed.add(()=>{
			create customize the UI component and mount it to the Container
			let item= createUIByName('BagItem.ui') as UserWidget
			canvas.addChild(item)
		})	
    }

	onDrop(InGemotry: Geometry, InDragDropEvent: PointerEvent, InOperation: DragDropOperation) {
		console.log("OnDrop"+InDragDropEvent.screenSpacePosition)
		return true
    }
}

  • The final achieved effect:

  • Please note: This is just to demonstrate the use of drag events, in fact, if you want to make a fully functional bags, not only the styles of each slot in the bags must be passed over, but also the corresponding item function The information is passed on, and everyone can try it on their own.

Important Notes

  • button, text button, mask, button and other button categories The widget does not support the use of UI drag and drop events (if pressed to the button class component, the click event will be directly triggered, The drag-and-drop event cannot be triggered), so use the image widget as the draggable UI if you want to listen for image as a draggable UI if it is clickTouch events can be used

  • Note: The alignment of the Root node of the dragged UI should be set to the top left align
  • The onDrop event cannot be triggered at the edge of the camera slide area at the moment, so try to avoid this