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.
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!
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.
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.
Yeah I already added controller navigation and that works great. this is what a want to preview bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
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.
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
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.
Posting my whole code in case if this helps. I appreciate ANY HELP!
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Linq;
using TMPro;
namespace mfps.Shop
{
public class bl_ShopItemUI : bl_ShopItemUIBase, IPointerEnterHandler, ISelectHandler
{
public TextMeshProUGUI NameText;
public TextMeshProUGUI typeText;
public Image[] Icons;
public RectTransform BuyButton;
public GameObject OwnedUI;
public GameObject BuyUI;
public GameObject levelBlockUI;
public bl_PriceUI priceUI;
public MonoBehaviour[] oneTimeUsed;
public int ID { get; set; } = 0;
public ShopItemType TypeID;
private ShopProductData Info;
private bool isOwned = false;
private bool canPurchase = true;
/// <summary>
///
/// </summary>
/// <param name="data"></param>
public override void Setup(ShopProductData data)
{
foreach (Image i in Icons) { i.gameObject.SetActive(false); }
priceUI?.SetActive(false);
Info = data;
ID = data.ID;
TypeID = data.Type;
NameText.text = Info.Name.ToUpper();
string typeName = data.Type.ToString();
typeName = string.Concat(typeName.Select(x => System.Char.IsUpper(x) ? " " + x : x.ToString())).TrimStart(' ');
typeText.text = typeName.Localized(data.Type.ToString().ToLower()).ToUpper();
LayoutRebuilder.ForceRebuildLayoutImmediate(NameText.transform.parent.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(typeText.transform.parent.GetComponent<RectTransform>());
//that's kinda dirty but it works :)
foreach (MonoBehaviour b in oneTimeUsed) { Destroy(b); }
// If this item is free
// IsUnlocked will return True if the local player is not logged or is a guest.
// So a further conditional is required for that scenario.
if (Info.UnlockabilityInfo.IsUnlocked(ID))
{
#if ULSP
// if the user has not been logged or if it's a guest, don't let him select the weapons.
if((!bl_DataBase.IsUserLogged || bl_DataBase.IsGuest) && Info.UnlockabilityInfo.CanBePurchased())
{
ShowBlockUI();
}
else
{
// Means that the weapon is unlocked for this player
ShowOwnedUI();
}
#else
ShowOwnedUI();
#endif
}
else
{
if (Info.UnlockabilityInfo.CanBePurchased())
{
ShowBlockUI();
}
else
{
// If this object only can be unlocked by level up.
ShowBlockUI(false);
}
}
int iconImageID = 0;
if (Info.Type == ShopItemType.PlayerSkin) iconImageID = 1;
else if (Info.Type == ShopItemType.WeaponCamo) iconImageID = 2;
SetIcon(Info.GetIcon(), iconImageID);
}
/// <summary>
///
/// </summary>
void ShowBlockUI(bool requirePurchase = true)
{
priceUI.ShowPrices(Info.UnlockabilityInfo);
priceUI.SetActive(requirePurchase);
BuyUI.SetActive(requirePurchase);
isOwned = false;
canPurchase = requirePurchase;
BuyButton.gameObject.SetActive(requirePurchase);
OwnedUI.SetActive(false);
if (levelBlockUI != null) levelBlockUI.SetActive(!requirePurchase);
}
/// <summary>
///
/// </summary>
void ShowOwnedUI()
{
BuyUI.SetActive(false);
isOwned = true;
canPurchase = false;
GetComponent<Selectable>().interactable = false;
OwnedUI.SetActive(true);
if (levelBlockUI != null) levelBlockUI.SetActive(false);
}
/// <summary>
///
/// </summary>
void SetIcon(Sprite icon, int id)
{
Icons[id].gameObject.SetActive(true);
Icons[id].sprite = icon;
}
public void OnBuy()
{
#if ULSP && SHOP
if (!bl_DataBase.IsUserLogged)
{
bl_ShopNotification.Instance?.Show("You need an account to make purchases.").Hide(3);
Debug.LogWarning("You has to be login in order to make a purchase.");
return;
}
else
{
if (bl_UserWallet.HasFundsFor(Info.Price))
{
bl_ShopManager.Instance.PreviewItem(Info, BuyButton.position);
}
else
{
bl_ShopManager.Instance.NoCoinsWindow.SetActive(true);
}
}
#else
Debug.LogWarning("You need have ULogin Pro enabled to use this addon");
return;
#endif
}
public void OnPointerEnter(PointerEventData eventData)
{
eventData.selectedObject = gameObject;
bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
}
public void OnSelect(BaseEventData eventData)
{
eventData.selectedObject = gameObject;
bl_ShopManager.Instance.Preview(Info, isOwned, canPurchase);
}
}
}
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.