Search Unity

Raycast towards UI elements?

Discussion in 'UGUI & TextMesh Pro' started by vexe, Dec 7, 2014.

  1. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    So I had this idea which is very straightforward in theory of how to tell if a multi-dimensional item can fit in a certain inventory region or not. Take a 2x2 item for ex, I divide it into 4 equal sections, take the center of each section and cast a ray from that center towards the inventory, if all 4 rays intersect with empty slots, then the item can fit, otherwise not. Here's what I mean:



    The first item doesn't fit, cause there's one square intersecting with an occupied slot. The second item fits, there's nothing in its way.

    The question is, how to raycast from the items to the inventory? My slots consist of Button/Image combo with no Colliders so I don't think Physics.Raycast work, does it? I just came across RaycastResult and GraphicRaycaster. But there's barely anything mentioned about them, no description, no usage examples, no nothing.

    Any light shed on the subject is appreciated. Thanks.
     
  2. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    One detail I forgot to mention is that, I don't do this when I pickup an item, instead I just find the first available region for the item to fit in and add it. I do the raycasting thing when I'm holding an item with the mouse and want to place it somewhere else (player could hold the item, rotate it, swap etc)
     
  3. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    So I figured it out, all I needed to know was that there's a RaycastAll(PointerEventData, List<RaycastResult) in EventSystem and that I need to instantiate an event data and set its position where I want the raycast to be, in my case it's the center of each item division

    Code (csharp):
    1.  
    2.     bool DoesItemFit(Item item)
    3.      {
    4.        var pos = item.InvRepresentation.transform.position;
    5.        var system = EventSystem.current;
    6.        var hits = new List<RaycastResult>();
    7.        var pointer = new PointerEventData(system);
    8.  
    9.        float width = slotSize.x;
    10.        float height = slotSize.y;
    11.        int nHits = 0;
    12.  
    13.        for(int i = 0; i < item.nRowsRequired; i++)
    14.        {
    15.          float y = (height / 2) + (height * i);
    16.  
    17.          for(int j = 0; j < item.nColsRequired; j++)
    18.          {
    19.            float x = (width / 2) + (width * j);
    20.  
    21.            pointer.position = new Vector2(pos.x + x, pos.y - y);
    22.            system.RaycastAll(pointer, hits);
    23.  
    24.            for(int k = 0; k < hits.Count; k++)
    25.            {
    26.              var hit = hits[k];
    27.              var go = hit.gameObject;
    28.              var slot = go.GetComponent<Slot>();
    29.              if (slot != null)
    30.              {
    31.                if (!slot.IsEmpty)
    32.                  return false;
    33.                nHits++;
    34.              }
    35.            }
    36.          }
    37.        }
    38.  
    39.        return nHits == item.nRowsRequired * item.nColsRequired;
    40.      }
    41.  
     
    Last edited: Dec 7, 2014
    Misnomer likes this.
  4. Galactic_Muffin

    Galactic_Muffin

    Joined:
    Aug 14, 2013
    Posts:
    67
    this is super cool! i dont quite understand how the eventSystem works and what it is capable of, but i'm trying to achieve multitouch to instantiate 2 joysticks for a top-down duel shooter for mobile devices. i'm using ray cast code to try and spawn in the joysticks but UGUI cant be effected by ray-casts apparently and there is no multitouch functionality to the eventSystem that i know of.
     
  5. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @Galactic_Muffin

    Hi! - Check Touch class from scripting manual, it works with multi touch, however, Input class / EventSystem only works with single click in Editor.
    And you can't basically "click" on empty space around your joystick, I've got hard time figuring my way around this thinking - I guess the best way is to have sort of spawn script, on empty area with transparent Image component, click on this area spawns/unhide your joystick.

    And definitely cool thread - funny I searched for raycasting UI and found this thread just 2 hours ago too.