Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question What is the keyboard/gamepad equivalent to OnPointerEnter?

Discussion in 'Scripting' started by calenmac, Sep 7, 2023.

  1. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Hello All,

    Does anyone know the OnPointerEnter (As per Unity - Scripting API: UI.Selectable.OnPointerEnter (unity3d.com)) equivalent for keyboard/gamepad?

    Example: I have a script that uses this in my game so whenever I hover the mouse over an object (weapon), it shows information of that weapon.

    If I was to modify this for a selected object (such as a keyboard or controller), do you know what changes I would make for the below:

    public void OnPointerEnter(PointerEventData eventData)
    {
    bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
    }

    I greatly appreciate any help!

    UPDATE:

    I fixed it. It was a navigation issue that was causing the intermittent issues and the main issue was GetComponent<Selectable>().interactable = true; (was false)
     
    Last edited: Sep 30, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    This ultimately depends on how the user is interacting with your UI via a controller, and how your UI is set up. So it's not really answerable in a vacuum.

    Eg, if the navigating via the controller moves through a list of different selectable elements, you hook into the callback of what that element is selected/active.
     
  3. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Thanks for the quick reply. I added controller/keyboard support by creating a separate script with a co-routine to auto select the first object of a scene/window. I am unsure how I can modify my on pointer script to also so the same thing when the object is selected. Off the top of your head can you provide an example script so I can get the basic idea of what to do? I appreciate any help!
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    You don't need to modify your existing method. You will need more code.

    Again, I don't know the specifics of your UI set up. Assuming you're using buttons, you might need to implement
    ISelectHandler
    . Again, taking wild punts here.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,710
    To simultaneously support input contexts that may or may not have something as critical as "mouse dwell" to give feedback is always a chore. The best way to get a good start on it is to outline the events you want to handle and think about how they will be presented:

    - hover
    - unhover
    - selection
    - deselection
    - activate
    - deactivate

    etc

    Often times it may be useful to have two versions of your UI scene or UI prefab, one for console DPAD+A/B type use and one for mouse, and then plumb them both into the same controller, and only activate one or the other depending on target playmode.

    It gets really tricky when you are on PC and the user may put down the mouse and pick up the controller. Again, detect it and be explicit with what you enable / disable.
     
  6. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Thanks . I’m not having any luck with trying this yet but I’m trying lol
     
  7. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Yeah I already added controller navigation and that works great. this is what a want to preview bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);

    I trying to do something like
    public void OnSelect(EventSystems.BaseEventData eventData);

    as @spiney199 mentioned but doesn’t seem to be working for me. I can’t seem to find any videos of examples of how this could be accomplished either.
     
  8. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    yup I tired the ISelectHandler and added the following:

    public void OnSelect(BaseEventData eventData)
    {
    bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);

    }

    But this didnt do anything. Any thoughts on why this doesnt work but the mouse pointer does?
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    For it to work I believe the component needs to be on the same game object as another component that is Selectable (as in it inherits from
    UnityEngine.UI.Selectable
    ), such as a button.
     
  10. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    I do have the script added on the selectables. Odd this is, ive noticed very intermittently the weapon shows the info but only when selecting a certain weapon first then going to that one particular weapon. this doesnt make any sense lol
     
  11. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Any one have any additional thoughts on this? I have noticed a pattern to when this intermittently works (for only one object), i have to use the mouse first to show the preview, then when I use the game pad navigation for another weapon, the preview works for the gamepad.

    Odd that:


    Code (CSharp):
    1. public void OnPointerEnter(PointerEventData eventData)
    2.         {
    3.             eventData.selectedObject = gameObject;
    4.             bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
    5.  
    6.  
    7.         }
    works but not:


    Code (CSharp):
    1. public void OnSelect(BaseEventData eventData)
    2.     {
    3.  
    4.    
    5.             eventData.selectedObject = gameObject;
    6.             bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
    7.         }
    8.     }
    9. }
    Posting my whole code in case if this helps. I appreciate ANY HELP!

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using System.Linq;
    5. using TMPro;
    6.  
    7. namespace mfps.Shop
    8. {
    9.     public class bl_ShopItemUI : bl_ShopItemUIBase, IPointerEnterHandler, ISelectHandler
    10.     {
    11.         public TextMeshProUGUI NameText;
    12.         public TextMeshProUGUI typeText;
    13.         public Image[] Icons;
    14.         public RectTransform BuyButton;
    15.         public GameObject OwnedUI;
    16.         public GameObject BuyUI;
    17.         public GameObject levelBlockUI;
    18.         public bl_PriceUI priceUI;
    19.         public MonoBehaviour[] oneTimeUsed;
    20.         public int ID { get; set; } = 0;
    21.         public ShopItemType TypeID;
    22.  
    23.         private ShopProductData Info;
    24.         private bool isOwned = false;
    25.         private bool canPurchase = true;
    26.  
    27.         /// <summary>
    28.         ///
    29.         /// </summary>
    30.         /// <param name="data"></param>
    31.         public override void Setup(ShopProductData data)
    32.         {
    33.             foreach (Image i in Icons) { i.gameObject.SetActive(false); }
    34.             priceUI?.SetActive(false);
    35.             Info = data;
    36.             ID = data.ID;
    37.  
    38.             TypeID = data.Type;
    39.             NameText.text = Info.Name.ToUpper();
    40.             string typeName = data.Type.ToString();
    41.             typeName = string.Concat(typeName.Select(x => System.Char.IsUpper(x) ? " " + x : x.ToString())).TrimStart(' ');
    42.             typeText.text = typeName.Localized(data.Type.ToString().ToLower()).ToUpper();
    43.             LayoutRebuilder.ForceRebuildLayoutImmediate(NameText.transform.parent.GetComponent<RectTransform>());
    44.             LayoutRebuilder.ForceRebuildLayoutImmediate(typeText.transform.parent.GetComponent<RectTransform>());
    45.             //that's kinda dirty but it works :)
    46.             foreach (MonoBehaviour b in oneTimeUsed) { Destroy(b); }
    47.  
    48.             // If this item is free
    49.             // IsUnlocked will return True if the local player is not logged or is a guest.
    50.             // So a further conditional is required for that scenario.
    51.             if (Info.UnlockabilityInfo.IsUnlocked(ID))
    52.             {
    53. #if ULSP
    54.                 // if the user has not been logged or if it's a guest, don't let him select the weapons.
    55.                 if((!bl_DataBase.IsUserLogged || bl_DataBase.IsGuest) && Info.UnlockabilityInfo.CanBePurchased())
    56.                 {
    57.                     ShowBlockUI();
    58.                 }
    59.                 else
    60.                 {
    61.                     // Means that the weapon is unlocked for this player
    62.                     ShowOwnedUI();
    63.                 }
    64. #else
    65.                 ShowOwnedUI();
    66. #endif
    67.             }
    68.             else
    69.             {
    70.                 if (Info.UnlockabilityInfo.CanBePurchased())
    71.                 {
    72.                     ShowBlockUI();
    73.                 }
    74.                 else
    75.                 {
    76.                     // If this object only can be unlocked by level up.
    77.                     ShowBlockUI(false);
    78.                 }
    79.             }
    80.  
    81.             int iconImageID = 0;
    82.             if (Info.Type == ShopItemType.PlayerSkin) iconImageID = 1;
    83.             else if (Info.Type == ShopItemType.WeaponCamo) iconImageID = 2;
    84.  
    85.             SetIcon(Info.GetIcon(), iconImageID);
    86.         }
    87.  
    88.         /// <summary>
    89.         ///
    90.         /// </summary>
    91.         void ShowBlockUI(bool requirePurchase = true)
    92.         {
    93.             priceUI.ShowPrices(Info.UnlockabilityInfo);
    94.             priceUI.SetActive(requirePurchase);
    95.             BuyUI.SetActive(requirePurchase);
    96.             isOwned = false;
    97.             canPurchase = requirePurchase;
    98.             BuyButton.gameObject.SetActive(requirePurchase);
    99.             OwnedUI.SetActive(false);
    100.             if (levelBlockUI != null) levelBlockUI.SetActive(!requirePurchase);
    101.         }
    102.  
    103.         /// <summary>
    104.         ///
    105.         /// </summary>
    106.         void ShowOwnedUI()
    107.         {
    108.             BuyUI.SetActive(false);
    109.             isOwned = true;
    110.             canPurchase = false;
    111.             GetComponent<Selectable>().interactable = false;
    112.             OwnedUI.SetActive(true);
    113.             if (levelBlockUI != null) levelBlockUI.SetActive(false);
    114.         }
    115.  
    116.         /// <summary>
    117.         ///
    118.         /// </summary>
    119.         void SetIcon(Sprite icon, int id)
    120.         {
    121.             Icons[id].gameObject.SetActive(true);
    122.             Icons[id].sprite = icon;
    123.         }
    124.  
    125.         public void OnBuy()
    126.         {
    127. #if ULSP && SHOP
    128.  
    129.             if (!bl_DataBase.IsUserLogged)
    130.             {
    131.                 bl_ShopNotification.Instance?.Show("You need an account to make purchases.").Hide(3);
    132.                 Debug.LogWarning("You has to be login in order to make a purchase.");
    133.                 return;
    134.             }
    135.             else
    136.             {
    137.                 if (bl_UserWallet.HasFundsFor(Info.Price))
    138.                 {
    139.                     bl_ShopManager.Instance.PreviewItem(Info, BuyButton.position);
    140.                 }
    141.                 else
    142.                 {
    143.                     bl_ShopManager.Instance.NoCoinsWindow.SetActive(true);
    144.                 }
    145.             }
    146. #else
    147.                         Debug.LogWarning("You need have ULogin Pro enabled to use this addon");
    148.             return;
    149. #endif
    150.         }
    151.  
    152.         public void OnPointerEnter(PointerEventData eventData)
    153.         {
    154.             eventData.selectedObject = gameObject;
    155.             bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
    156.  
    157.  
    158.         }
    159.  
    160.  
    161.  
    162.     public void OnSelect(BaseEventData eventData)
    163.     {
    164.  
    165.    
    166.             eventData.selectedObject = gameObject;
    167.             bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
    168.         }
    169.     }
    170. }

    Also here is the console error:

    Attempting to select ShopItem (Template)(Clone) (UnityEngine.GameObject)while already selecting an object.
    UnityEngine.EventSystems.BaseEventData:set_selectedObject (UnityEngine.GameObject)
    MFPS.Shop.bl_ShopItemUI:OnSelect (UnityEngine.EventSystems.BaseEventData) (at Assets/Addons/Shop/Scripts/Runtime/UI/bl_ShopItemUI.cs:167)
    UnityEngine.EventSystems.BaseEventData:set_selectedObject (UnityEngine.GameObject)
    MFPS.Shop.bl_ShopItemUI:OnPointerEnter (UnityEngine.EventSystems.PointerEventData) (at Assets/Addons/Shop/Scripts/Runtime/UI/bl_ShopItemUI.cs:155)
    UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)
     
    Last edited: Sep 18, 2023
  12. karliss_coldwild

    karliss_coldwild

    Joined:
    Oct 1, 2020
    Posts:
    530
    Carefully read what the error is telling and think what it means.

    "Attempting to select ShopItem while already selecting an object."

    Now take a look at your OnSelect callback. What is the first thing you do? You select an object.
     
  13. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Thanks for helping out here! I even get this error with onselect omitted from my script and just using the onpointer. Although, the pointer always works fine.

    So, I even tried removing the Onpointerenter and keeping the OnSelect. OnSelect still doesnt preview bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);

    No console error either. This is driving me insane lol.
     
  14. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    Anyone have any thoughts on this? IM STILL STUCK!
     
  15. calenmac

    calenmac

    Joined:
    Mar 3, 2019
    Posts:
    28
    UPDATE:

    I fixed it. It was a navigation issue that was causing the intermittent issues and the main issue was GetComponent<Selectable>().interactable = true; (was false)
     
    Last edited: Sep 30, 2023