Forum rules - please read before posting.

On screen arrows in menu

Hi there,

I wasn't sure how to go about doing this, but I wanted to make a menu that emulated a phone's screen. It's built to Android so there would be 2 arrows you'd touch to go up and down the menu options.
The options would be like "Messages" "Options" "Exit" with 2 arrows that make the selection rectangle go up and down this.

It would basically be like this but with 2 on screen arrows.

I've already made the menu graphically in UnityUI itself but now I'm not sure what to do to make the selection go up and down with the arrows part. Is there something I can do in AC for this?

I hope that makes sense I'm bad at explaining lol thanks so much!

Comments

  • FWIW, this may be possible without AC by relying on Unity's ScrollRect component, which your menu Button elements can be placed inside.

    Sticking with AC, though, you could either rely on scripting to show/hide your Buttons based on how many times your scroll arrow has been pressed - or just do it with Inventory.

    If you create a new Inventory category named e.g. PhoneMenuItems, then create a new Inventory item for each item (Phonebook, Messages etc), and have the Player carry the on start, you can then display them via an InventoryBox that's filtered to only show items in the PhoneMenuItems category. This would replace your individual Button elements, with each Button's ActionList being moved to its corresponding Inventory item's "Use" interaction.

    This way, you'd then be able to use regular Buttons of type "Offset Element Slot" to scroll through the InventoryBox to reveal the different items.

  • edited August 2022

    Hi Chris,
    Thanks for that! Doing it in AC works for me :smile:

    I've got it all set up but the issue is when doing the "offset element slot" it doesn't seem to select the inventory item?

    When I click the "OK" button that would select the messages option/inventory item, I did a debug comment to console saying "test" after checking if selected inventory item was "messages" and nothing worked.

    I scrolled back and forth and ran it but the same thing happened. I tried it again with "check if has 'message' inventory item" and it worked so it has it, but it doesn't seem to select it? Select first element is ticked on the menu too.

  • edited August 2022

    If you want to rely on a separate "OK" button to run the Inventory item's Interaction, instead of tapping the Item itself, you need to attach a script that records the last item to be selected and provides a function to then use it. Something like this:

    using UnityEngine;
    using AC;
    
    public class SelectPhoneItem : MonoBehaviour
    {
    
        public string menuName;
        public string inventoryBoxName;
        public InvItem selectedItem;
    
        private void OnEnable () { EventManager.OnMouseOverMenu += OnMouseOverMenu; }
        private void OnDisable () { EventManager.OnMouseOverMenu -= OnMouseOverMenu; }
    
        private void OnMouseOverMenu (Menu _menu, MenuElement _element, int _slot)
        {
            if (_menu.title == menuName && _element != null && _element.title == inventoryBoxName)
            {
                MenuInventoryBox inventoryBox = _element as MenuInventoryBox;
                selectedItem = inventoryBox.GetItem (_slot);
            }
        }
    
        public void UseItem ()
        {
            if (selectedItem != null)
            {
                selectedItem.RunUseInteraction ();
            }
        }
    
    }
    
  • Thanks for that, I was going to use that as I don't know how to code it haha. The only issue is I get the error "Cannot implicitly convert type AC.InvItem' tobool'" ?

  • I've updated the script - try it now. If you get another error, share it in full - stacktrace included.

  • Sorry to keep coming back to this - the code has no more errors but it doesn't seem to do anything. I have it attached to my OK button. Is that right?

  • You'll need to enter your Menu and InventoryBox names into its Inspector, and then have your OK Button run the component's "UseItem" function when clicked.

  • That's what I've done :D

    Is there a way for me to debug the name of what item is currently selected?

  • edited August 2022

    That's what I've done

    When using the Object: Call event Action, you need to assign the object that the script is attached to as a component - not the script itself.

    You won't be able to use Object: Call event here, since it'll be the scene instance of the prefab you want to affect - not the prefab itself. You could use Object: Send message, but you don't actually need to use an ActionList at all. Using the Button component in the UI prefab to run its own UseItem function should be enough.

    Is there a way for me to debug the name of what item is currently selected?

    Paste this at the bottom of the OnMouseOverMenu function:

    if (selectedItem != null) Debug.Log ("Selected item: " + selectedItem.label);
    
  • edited August 2022

    Hi Chris,
    Sorry about this but I'm really struggling. In PhoneOK's button component I have the OnClick set to the button itself (and tried the phone object too) with SelectPhoneItem.UseItem and its not working, nothing happens even when trying to do a debug.log in UseItem and OnMouseOverMenu.

    I did to a debug.log for else on if (selectedItem != null) and it comes up - so I don't think any items is being selected?

  • Move the Debug.Log statements to the inside of the function's second set of brackets, so that they only show if the Menu and Element names match up - do they still show?

  • No they dont, not when I click the button

  • edited August 2022

    The script works by listening in to clicks on the InventoryBox to determine what the last-clicked item is. Are you clicking the InventoryBox before clicking "OK"? If not, does it work if you do so, and how is it you're intending to have the box be selected?

  • Hi Chris,
    I managed to narrow the debug.log not appearing because one of my others menus were underneath and it was picking that up instead, so I turned it off and that works and it says the correct item.

    My main issue left right now is trying to get the up and down buttons on the phone menu to select the next/previous slot in the InventoryBox as it only picks it up when you hover over the menu (which is as intended i guess). It scrolls up and down but doesn't select anything if that makes sense. Is there a way to do this with AC?

  • edited August 2022

    You'd have to use scripting to replace the up/down button functionality, as (I'm guessing) you'd want to use them scroll through each item in the InventoryBox and only "shift" the boxes once reaching the end.

    This'll also need a reworked script for clicking "OK", because not clicking the Inventory itself means the events used earlier won't be run.

    Try this:

    using UnityEngine;
    using UnityEngine.UI;
    using AC;
    
    public class SelectPhoneItem : MonoBehaviour
    {
    
        public string menuName;
        public string inventoryBoxName;
        private int selectedIndex;
        public UnityEngine.UI.Button[] inventoryButtons;
    
        public void ClickUp ()
        {
            selectedIndex--;
            if (selectedIndex < 0)
            {
                selectedIndex = 0;
                InventoryBox.Shift (AC_ShiftInventory.ShiftPrevious, 1);
                inventoryButtons[selectedIndex].Select ();
            }
        }
    
        public void ClickDown ()
        {
            selectedIndex ++;
            if (selectedIndex >= inventoryButtons.Length)
            {
                selectedIndex = inventoryButtons.Length - 1;
                InventoryBox.Shift (AC_ShiftInventory.ShiftNext, 1);
                inventoryButtons[selectedIndex].Select ();
            }
        }
    
        public void ClickOK ()
        {
            InvItem selectedItem = InventoryBox.GetItem (selectedIndex);
            if (selectedItem != null)
            {
                selectedItem.RunUseInteraction ();
            }
        }
    
        private MenuInventoryBox InventoryBox { get { return PlayerMenus.GetElementWithName (menuName, inventoryBoxName) as MenuInventoryBox; }}
    
    }
    

    Detach the Up/Down/OK Buttons from AC's Menu Manager (delete the Elements) and attach the script to the UI prefab. Have the three Unity Buttons run this component's ClickUp/ClickDown/ClickOK functions respectively when clicked.

  • edited August 2022

    Thanks Chris - I'm getting this "The name `selectedItem' does not exist in the current context" - I tried copying over private InvItem selectedItem but it threw me an error instead haha

    Edit: would it be private int selectedItem ?

  • Sorry - another typo. I've corrected the above - give it another try.

  • edited September 2022

    Sorry to bring this back up! I hope it's okay!

    Thanks so much for the previous, I was just wondering - it all works perfectly, but is there a way to grab the second and third next inventory items?

    Say there's 3 inventorybox slots and the inventory items are:

    Apple
    Pineapple
    Chocolate
    Potato
    Orange
    Peach

    And on screen is the 3 slots with the current inventory items:

    Pineapple
    Chocolate
    Potato

    Is there a way for it to find the selectedItem2 and selectedItem3 instead of just the first one (Pineapple)? I'd love to have a button for each of the 3 slots!

    Sorry if this makes no sense I'm god awful at explaining hahaha

    Thank you so much and if its too convoluted or not possible don't worry I just thought I'd ask :)

  • It is - the InventoryBox.GetItem function above requires the index as a parameter - 0 = first, 1 = second, 2 = third.

    But, the script above doesn't limit itself to the first - the selectedIndex variable changes as the ClickUp and ClickDown functions are run.

    If you want to instead have separate ClickOK functions for each slot, which read a specific slot index, you can instead use:

    using UnityEngine;
    using AC;
    
    public class SelectPhoneItem : MonoBehaviour
    {
    
        public string menuName;
        public string inventoryBoxName;
    
        public void ClickSlotOne ()
        {
            ClickOK (0);
        }
    
        public void ClickSlotTwo ()
        {
            ClickOK (1);
        }
    
        public void ClickSlotThree ()
        {
            ClickOK (2);
        }
    
        private void ClickOK (int slotIndex)
        {
            InvItem selectedItem = InventoryBox.GetItem (slotIndex);
            if (selectedItem != null)
            {
                selectedItem.RunUseInteraction ();
            }
        }
    
        private MenuInventoryBox InventoryBox { get { return PlayerMenus.GetElementWithName (menuName, inventoryBoxName) as MenuInventoryBox; }}
    
    }
    

    Where ClickSlotOne, ClickSlotTwo and ClickSlotThree are the public functions to call via events.

  • Thanks so much as always Chris, lifesaver!! :)

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.