Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Select with click/tap, drag'n'drop

Discussion in 'Project Tiny' started by Demoralizator, Dec 20, 2018.

  1. Demoralizator


    Apr 6, 2015
    I'm trying to make a card game in Tiny and i wonder, what is the best way to implement a click on a sprite and dragging and dropping a sprite? Raycast, or maybe UI?
    I would really appreciate some clarifications on how Raycast works in Tiny.
    LauraLaureus likes this.
  2. LauraLaureus


    Oct 5, 2018
    I'm still playing with Tiny but In the Match-Three example they select the gems by checking the mouse/touch position is in the sprite limits.

    Since I really don't like to perform all the calculation for every entity in the game I reasearched in the forums ( ) and found a component called "MouseInteraction" that has a property called "clicked", but for me it always return false including when I force the system to perform after Input Fence.

    Also in the forums is shown a callback way but you cannot perform operations with (in the case of Behaviour systems) since it's another scope.

    So I thing the only stable way to do this is in the way the tutorial shows.
    Demoralizator likes this.
  3. Nkon


    Unity Technologies

    Jun 12, 2017

    Here's a small example demonstrating image dragging inside a UICanvas.

    You need to define two custom components for this system to work. They are 'Draggable' and 'Dragged'. These components don't need to have any fields in them.

    The code assumes you're using the default 'game' namespace for components and systems.

    Any objects you wish to drag should have the MouseInteraction and Draggable components added to them in the Editor.

    Code (JavaScript):
    1. namespace game {
    2. export class EntityDragSystem extends ut.ComponentSystem {
    3.     static initialized = false;
    5.     OnMouseDown(e: ut.Entity): void {
    6.         console.log("Mouse down on Entity #" + e.index);
    7.         // add a game.Dragged component to the clicked entity
    8.         const oneworld = ut.HTML.HTMLService.oneWorld() as ut.World;
    9.         oneworld.addComponent(e, game.Dragged);
    10.     }
    12.     OnMouseUp(e: ut.Entity): void {
    13.         console.log("Mouse up on Entity #" + e.index);
    14.         // remove a game.Dragged component from the clicked entity
    15.         const oneworld = ut.HTML.HTMLService.oneWorld() as ut.World;
    16.         oneworld.removeComponent(e, game.Dragged);
    17.     }
    19.     OnUpdate(): void {
    20.         // set up callbacks for all entities with the required components
    21.         if (!EntityDragSystem.initialized) {
    22.   [ut.Entity, ut.UIControls.MouseInteraction, game.Draggable],
    23.                 (entity, mouseInteraction, draggable) => {
    24.                     ut.UIControls.UIControlsService.addOnDownCallback(
    25.               , entity, this.OnMouseDown);
    26.                     ut.UIControls.UIControlsService.addOnUpCallback(
    27.               , entity, this.OnMouseUp);
    28.                 });
    30.             EntityDragSystem.initialized = true;
    31.             console.log("Callbacks added");
    32.         }
    33.         // calculate new position for any dragged entities
    34.         const displayInfo =;
    35.         let mousePos = ut.Core2D.Input.getInputPosition();
    36.         mousePos.x -= displayInfo.frameWidth / 2;
    37.         mousePos.y -= displayInfo.frameHeight / 2;
    38.         // update all dragged entities to use the new position
    39.[ut.Entity, game.Dragged, ut.UILayout.RectTransform],
    40.             (entity, dragged, rectTransform) => {
    41.                 rectTransform.anchoredPosition = mousePos;
    42.             });
    43.     }
    44. }
    45. }
    Demoralizator likes this.
  4. Demoralizator


    Apr 6, 2015
    Hey, Laura. Thanks for the suggestion, but i think Match3 approach is only applicable when you have some kind of a grid and the elements are not overlapping.
    Hey, Nkon. Thanks a lot. I'll try it right away. I'm still not sure how to implement drop though.

    And my question about Raycast still stands. Would be nice to wrap my head around such a versatile tool.
  5. nik_ai


    Jun 14, 2017
    Make sure Sprite2DRendererHitBox2D component attached to that entity which you want to hit.

    Code (JavaScript):
    1. let _hitResult = ut.HitBox2D.HitBox2DService.hitTest(,tapPos,camEntity);
    3. if(!_hitResult.entityHit.isNone())
    4. {
    5. console.log("Something hitted");
    6. console.log(;
    7. }
    Streamfall and Demoralizator like this.
  6. Streamfall


    Aug 8, 2011
    I'm also trying to accomplish this. I'm not receiving any hits.

    This seems to be a problem to converting camera space to world space, as I can output the positions of my sprites and position of raycast.

    EDIT 2
    Needed to convert the mouse position to world position, like so :
    let mousePos = ut.Core2D.Input.getInputPosition();
    let mp = ut.Core2D.Input.translateScreenToWorld(,mousePos);

    EDIT 3
    Could probably have just used :
    Last edited: Jan 8, 2019
    nik_ai likes this.
  7. nik_ai


    Jun 14, 2017
    You are right @Streamfall ,
    We have to convert mouse position to world position.
    I have used below method from TinyArmProject

    Code (JavaScript):
    1. //For getting mouse pointer position in world space
    2.         static getPointerWorldPosition(world: ut.World, cameraEntity: ut.Entity): Vector3 {
    3.             let displayInfo = world.getConfigData(ut.Core2D.DisplayInfo);
    4.             let displaySize = new Vector2(displayInfo.width, displayInfo.height);
    5.             let inputPosition = ut.Runtime.Input.getInputPosition();
    6.             return ut.Core2D.TransformService.windowToWorld(world, cameraEntity, inputPosition, displaySize);
    7.         }