Forum rules - please read before posting.

Arrange Interaction Icons based on their amount

I've one question... how can I set an Interaction Menu to arrange the icons based on the number of interactions?
I'll have a minimum of 1 and a max of 4 interactions and I'd like the icons to be arranged differently each time.
For example a hotspot can have 2 interactions (look and use), some other can have 4 (look, use, pull, pick), etc...
And I'd like my interaction icons to appear differently based on how many I have (now if I've 4 they all appear under the cursor). For instance: if there's one I want it under my cursor, if there are two I'd like them one on each side, etc.

Basically I'd like an arrangement like this:
https://ibb.co/XCgLY6v

I guess I've to write a custom script for the Interaction Menu?
But where? How?
(consider I'm a total noob with AC and Unity3D, but I've some basic experience with coding, especially for web design)

Thanks a lot!!

Comments

  • Yes, you'd need to rely on some scripting - but likely not much.

    First of all, you'll want to render your Menu with Unity UI if you aren't already. The "Adventure Creator" source option is better used for prototyping, with Unity UI the best option for fine tuning your Menu's appearance.

    See the Manual's "Unity UI menus" chapter, as well as this tutorial, for more on Unity UI menus. The default Interaction menu, however, comes with a Unity UI variant that you can access by changing the Source option to Unity Ui Prefab.

    You can then attach a script to your Canvas that re-arranges your UI Buttons according to how many are enabled - when AC turns your Interaction menu on, the Buttons will already be enabled/disabled accordingly.

    Something like this:
    http://pasteall.org/1488691/csharp

    Attach the component to the prefab, assign the Button/Vector fields, and they should update as they do in your image.

  • Dear Chris, thanks a lot for your reply.
    I'm trying to attach the script to the InteractionUI canvas, without success.

    Maybe I'm doing something wrong...
    Basically what I did is:

    • I opened my original "Interaction" menu, changed the variant to "Unity UI Prefab".
    • The linked Canvas prefab is called "InteractionUI", so I guessed it's there I should attach the script.
    • InteractionUI has two children: Panel and Grid. Should the script be attached to either of those? Or to the parent "InteractionUI"?
    • Anyway, I tried to all of them, opening the InteractionUI on the Inspector, Add Component, then "New Script" (copy-pasting the script you pasted here)
    • Maybe I understood wrongly the "assign the Button/Vector fields"?

    In any case it gives me error... What part am I doing it wrongly?

  • edited February 2019

    EDIT: I fixed the name of my script and now I don't have any errors, but the icons are not placed well... I got a warning: "Use, IsActive: False, Self: True, Hierarchy: True
    UnityEngine.Debug:Log(Object)" etc etc... Not sure why, working on it!

  • Just remove the Debug.Log statement on line 66 - that was just to aid writing it.

    You'll need to configure the Inspector to place the icons correctly.

  • edited February 2019

    Thanks again Chris and sorry for bothering... but not working yet :(

    Basically deleting line 66 I don't have anymore the warnings.
    But the icons aren't shown properly.
    Not sure what I'm doing wrongly.

    I've assigned my icons to the grid of the canvas InteractionUI.
    But they appear on top of my character (rather than cursor, even if in the Interaction Menu I set on cursor) and anyway they appear just in a row...

    Here I collected some screenshots in one picture to show some components.
    As you can notice the icons are in the canvas. I've assigned and set them to the script parameters. The Interaction Menu seems set properly.
    SCREENSHOT: https://ibb.co/yP6xtV9

    One thing I noticed: I cannot put the panel or grid into the "RecTransform boundary" slot of the Menu Interactions Properties. Neither the buttons into the "Linked button" properties of each interaction.
    I mean, I can drag and drop it there, but they disappear when I click play.

    Do I need to change something on the script?
    Or in the InteractionUI Inspector (Panel/Grid)?
    Or maybe there's something wrong in the AC Menu Interaction Properties?

    Thanks a lot and sorry for the noob questions...

    P.S. all the buttons work properly... I mean, clicking them they do what they are suppose to do, they are just shown wrongly.

  • EDIT: I fixed the "shown in a row" thing by deactivating the default "Grid Layout Group". Now the icons seems to react properly as I wanted. However they don't appear yet around the cursor but at the center of the screen. I guess it's something related with Canvas position? But in my Interaction Menu Properties it's set "Appear at Cursor and Freeze"... Working on it.

  • EDIT 2: I fixed the icons position by dragging the "GRID" instead of "PANEL" to the RecTransform boundary. Now everything seems to work perfectly... BUT!!! There's a but... Basically the first time I click on a hotspot the icons are in the wrong position. If I click a second time they are ok. If I click a hotstop that has the icons in a way and then a hotspot that has icons in another way, the position is wrong. If I re-click the same hotspot, they are then correct. I guess this has something to do with the script... therefore not sure how to fix it!

  • edited February 2019

    UPDATE: They work perfectly if the "Position type" is set "On Hotspot". But if I choose "Appear at Cursor and Freeze", then I've that problem... basically I need two clicks to get them in the correct place because somehow it "remembers" the previous clicked position... And of course I want them to "Appear at Cursor and Freeze"! D'oh!

  • UPDATE 2: I recorded a video to show the behavior of the icons on my clicks. There's also another problem that I don't have if I use the AC basic menu: when I click on an item in the inventory, the interaction icon appears behind it. (but the Interaction Menu is set to be on top of the Inventory one, in fact it works properly if using the AC interaction... instead of the Unity Prefab).

    Here the video: https://youtube.com/watch?v=Lmp7KpC4fp4

    And sorry for everybody if I'm writing too much. I just hope it could be of any help for other people out there!

  • I cannot put the panel or grid into the "RecTransform boundary" slot of the Menu Interactions Properties. Neither the buttons into the "Linked button" properties of each interaction. I mean, I can drag and drop it there, but they disappear when I click play.

    As expected. Unity doesn't allow for a direct link to a nested child in a prefab, but all that matters is that it records the object's Constant ID. You should find the ID number on the GameObject's Constant ID component matches up with the Recorded ConstantID value in the Menu Manager.

    I fixed the icons position by dragging the "GRID" instead of "PANEL" to the RecTransform boundary.

    Yes, the "RectTransform Boundary" is what AC will re-position given your Menu's Position type field, so any other objects you want to move with it will have to be children of that boundary.

    basically I need two clicks to get them in the correct place because somehow it "remembers" the previous clicked position

    Likely a bug, which I'll look into. I can only see it occuring once at the start of the video, however. Are you double-clicking on the Hotspots, because otherwise they look OK?

    when I click on an item in the inventory, the interaction icon appears behind it

    See the Manual's "Menus overview" chapter. AC menus are rendered in the order they appear in the Menu Manager. Unity UI menus are rendered in order of the "Sort Order" values on their Canvas components.

  • Thanks again Chris for your time.
    So, getting back to you...

    • Yes, each item has the correct "Recorded ConstantID", so it's working in that sense (also because if I set my interaction to be "On Hotspot" or on "Following Cursor" it works perfectly).

    • I click my hotspots a single click. The first click they are wrong (at the beginning they appear out of screen, afterwards they somehow keep the previous hotspot order) then on a second click they get the right arrangement. See for example the behavior when I click the "trash bin" hotspot on my video.

    • Considering the arranging is correct on "On Hotspot" or "Following Cursor" I'm afraid it could be a bug with some AC script related with "Appear at Cursor and Freeze". A Unity coder suggested me that "it might be an issue with how their script calculates positions and how the child elements affect its calculation of the object's bounds".

    • Regarding the InteractionUI appearing under the Inventory Menu, I'm afraid it's because the Inventory Menu is AC, while the InteractionUI is now Unity Prefab. And on your manual is written: "AC menus will always appear above Unity UI ones." So there's no way to mix AC menus with Unity UI ones sorting them out? If I want my Inventory to be behind the Interaction interface, the only option is making the Inventory menu also a Unity UI Prefab?!

    Thanks a lot for your time!

  • I'm afraid it could be a bug with some AC script related with "Appear at Cursor and Freeze".

    If it's a bug, it's not one I can recreate. The Demo_MenuManager's Interaction menu also has a Unity UI variant set to Appear At Cursor Then Freeze. If you assign that Manager and configure the Interaction menu's Source to Unity Ui Prefab, does that exhibit the same behaviour?

    Please also share full Inspectors of your Canvas, Menu properties, and AC/Unity version numbers.

    If I want my Inventory to be behind the Interaction interface, the only option is making the Inventory menu also a Unity UI Prefab?!

    Correct. This is through no fault of AC, just the different UI-rendering techniques that Unity provides.

  • Ok, first of all, no problems for the Inventory/Interaction order, I'll create my Inventory with Unity Prefab, not a big deal.

    Regarding the Interaction UI. I tried assigning the Demo2D_MenuManager and configuring the Interaction. The problem is still there and exactly the same.

    Unity Version 2018.3.5f1
    AC Version v1.66.7

    Here a screenshot of what you asked (hope is fine I put everything on a single file):
    https://ibb.co/XDCnqtL

  • UPDATE: I managed to get the first click not appearing out of screen by adjusting/playing around with the Canvas size. Now that is solved, but I still have the problem on the first click. Like that it works only a second time I click the hotspot. This happens at the beginning of the "play". But also after I click a different hotspot, like if it kept in mind the old position of the icons, before starting sorting them out correctly on the second click (please note: I don't mean "double clicking", all my clicks are single clicks, just clicking twice on the same hotspost it makes it work).

    In this video you can clearly see that behavior:

    And I think somehow could be fixed changing the attached script "ArrangeInteractionIcons"...
    Maybe there should be some function to call the arranging on the first click and "forgetting" the previous click? I've the feeling the issue can be solve adding something on that script!

  • I was taking your meaning to be that this was an issue even without the custom script. Does the menu position itself correctly if ArrangeInteractionIcons is disabled/removed?

    Try this:
    http://pasteall.org/1495936/csharp

  • With the custom script disabled and the Grid Layout Group enabled, the icons were appearing correctly (just not in the arrangement I wanted, but according to the Grid Layout Group parameters).
    However, with the new script, everything seems to work like a charm!!!
    Thanks a lot!!!

  • This type of menu style is exactly what I'd like to create.
    Would you be willing to share the newest code that was shared? The PasteAll link is broken now and unable to see it. It would be very much appreciated, and it will be very helpful.

    By the way, well done on your game's progress! The UI style looks very polished and the game looks interesting.

  • I believe this was it:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.UI;
    using AC;
    
    public class ArrangeInteractionIcons : MonoBehaviour
    {
    
        public UnityEngine.UI.Button[] interactionButtons;
        public Vector2 bottomPosition;
        public Vector2 leftPosition;
        public Vector2 rightPosition;
        public Vector2 topPosition;
    
    
        private void OnEnable ()
        {
            EventManager.OnEnableInteractionMenus += RearrangeAllIcons;
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnEnableInteractionMenus -= RearrangeAllIcons;
        }
    
    
        private void RearrangeAllIcons (Hotspot hotspot, InvItem invItem)
        {
            RectTransform[] enabledButtonTransforms = GetEnabledButtonTransforms ();
    
            if (enabledButtonTransforms != null)
            {
                ArrangeButtons (enabledButtonTransforms);
            }
        }
    
    
        private void ArrangeButtons (RectTransform[] buttonTransforms)
        {
            switch (buttonTransforms.Length)
            {
                case 1:
                    buttonTransforms[0].localPosition = bottomPosition;
                    break;
    
                case 2:
                    buttonTransforms[0].localPosition = leftPosition;
                    buttonTransforms[1].localPosition = rightPosition;
                    break;
    
                case 3:
                    buttonTransforms[0].localPosition = leftPosition;
                    buttonTransforms[1].localPosition = rightPosition;
                    buttonTransforms[2].localPosition = bottomPosition;
                    break;
    
                case 4:
                    buttonTransforms[0].localPosition = leftPosition;
                    buttonTransforms[1].localPosition = rightPosition;
                    buttonTransforms[2].localPosition = topPosition;
                    buttonTransforms[3].localPosition = bottomPosition;
                    break;
    
                default:
                    break;
            }
        }
    
    
        private RectTransform[] GetEnabledButtonTransforms ()
        {
            List<RectTransform> buttonTransforms = new List<RectTransform>();
    
            foreach (UnityEngine.UI.Button button in interactionButtons)
            {
                if (button.gameObject.activeSelf)
                {
                    buttonTransforms.Add (button.GetComponent <RectTransform>());
                }
            }
    
            return buttonTransforms.ToArray ();;
        }
    
    }
    
  • Thank you, Chris. It's appreciated!

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.