Forum rules - please read before posting.

Unity UI and Object Highlighting Inventory Items After Pickup

Hello,

In my inventory prototype (made using AC only) I used the Object - Highlight - Pulse options in the ActionList Editor to allow a picked up item to auto open the inventory, add it with a little pulsing highlight around it and then auto-close the inventory again. It worked and looked great.

After switching to a Unity UI interface linked to AC I’m unsure how to re-create that. I tried for a while to get it working before searching the forums where I found a thread from 2017 that stated that highlighting inventory items doesn’t work with Unity UI. I was wondering if that was still the case now years later?

Towards the end of the thread there was some talk of a way around this but as I have little scripting experience I am a little unsure if that method is still applicable now and how I would even go about implementing it. I am crossing my fingers maybe there has since been some progress on this issue since then and a simpler fix?

Any help would be greatly appreciated. Also I was unsure if it was OK to start a new thread on this topic or if I should have just responded to the one from several years ago? Sorry I’m new to the forum.

Here's a link to the 2017 thread that mentions a similar issue towards the end:

https://adventurecreator.org/forum/discussion/6389/highlight-inventory-item-inside-menus-inventorybox

Comments

  • The highlighting effect is still AC-only, since this mode allows AC enough control over the menu system.

    With Unity UI, you'd likely do this by attaching an Animator to each inventory slot Button object, which features a Trigger parameter (e.g. "ShowHighlight") that - when invoked - animates the Button (or a child Image) that shows the highlighting effect.

    Can you share screens of what a typical inventory item should look like normally vs when highlighted? It may be that the highlighted item graphic needs to appear as an overlay on top of the regular one, fading in and out. The Animator component could handle the fading, but a (simple) custom script may be necessary to dynamically set the overlay's graphic to the intended inventory item highlight texture.

    I can assist with that if necessary, but first I will need to look into adding a custom event hook for when inventory items are highlighted in this way. This will make it possible to run such code (which would be necessary anyway to invoke the right Trigger parameter) just by using the Object: Highlight Action as normal.

    I'll look into including this as part of the next update, so maybe we should revist this thread once it's out.

  • Hey Chris,

    Thank you for the speedy reply. I will include a pic of my inventory slot image which is included inside the inventory bar prefab, as per your previous advice it is now positioned correctly and doesn’t interfere with the functionality of the slot button itself. (Thanks again for that!).

    https://imgur.com/a/tLl0KPj

    The typical main and active graphics for an inventory item (also shown in the pic) feature a base image of the same size but the active one has a glowing outline that extends a few pixels beyond that. I know that when using the object > highlight > pulse feature before that the active graphic can’t be the same exact size as the main one or it remained hidden behind the main graphic during the effect.

    It would be great to see this feature included in some way in a future update. I have a lot of work ahead of me so I can definitely return to this problem later if need be as long as there is hope on the horizon :)

  • That this is not implemented in the same way that the AC-source option provides is not for lack of wanting. It's a question of it not being possible in a way that's consistent and seamless. Though it may require a bit of side-scripting, going with Unity best-practices is the way to go here, I feel.

    Again, though, I can help with such scripting. Just bump this thread once the new release is out, and I'll see about providing something. If your highlight texture is essentially the normal one with a larger outline, then it should be a simple matter of having a child Image component that fade in and out through animation - with just a simple script to set the correct image and trigger the animation.

  • This will make it possible to run such code (which would be necessary anyway to invoke the right Trigger parameter) just by using the Object: Highlight Action as normal.
    I'll look into including this as part of the next update, so maybe we should revist this thread once it's out.

    Has this been implemented in any of the updates last year?
    I'm trying to achieve exactly the same as this thread.

    Also, not sure how I would go about implementing this:

    but a (simple) custom script may be necessary to dynamically set the overlay's graphic to the intended inventory item highlight texture.

  • Has this been implemented in any of the updates last year?

    The OnInventoryHighlight event was introduced in v1.71.0.

    a (simple) custom script may be necessary to dynamically set the overlay's graphic to the intended inventory item highlight texture.

    If you rely on Unity UI, you can hook into the event, and use its parameters to determine which associated Button component in the Inventory menu was affected:

    using AC;
    using UnityEngine;
    
    public class GetHighlightedInventoryPosition : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnInventoryHighlight_Alt += OnInventoryHighlight; }
        private void OnDisable () { EventManager.OnInventoryHighlight_Alt -= OnInventoryHighlight; }
    
        private void OnInventoryHighlight (InvInstance invInstance, HighlightType highlightType)
        {
            MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName ("MyMenu", "MyInventoryBox") as MenuInventoryBox;
            int slot = inventoryBox.GetItemSlot (invInstance);
            UnityEngine.UI.Button uiButton = inventoryBox.uiSlots [slot].uiButton;
            Vector3 inventoryIconPosition = uiButton.GetComponent <RectTransform>().position;
        }
    
    }
    
  • Ok thanks, I've created the script (and updated the MyMenu & MyInventoryBox names to my own).
    -> Do I attach this script to the root of the Unity UI Inventory prefab?
    -> Or to each inventory slot in the prefab?

    I've created an animator for each inv Slot with a 'ShowHighlight' trigger condition as described in this thread.
    I also attached a child raw image (no texture selected) to each inv Slot.

    In my actionlist I use the 'Object: Highlight Inventory item' function, but it doesn't work as it did in AC mode. What am I missing?

  • The script above was only an example on how to access the associated Button component of the item in question. If you want to invoke a Trigger on that Button's Animator, you can use something like this:

    using AC;
    using UnityEngine;
    
    public class TriggerHighlightAnimation : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnInventoryHighlight_Alt += OnInventoryHighlight; }
        private void OnDisable () { EventManager.OnInventoryHighlight_Alt -= OnInventoryHighlight; }
    
        private void OnInventoryHighlight (InvInstance invInstance, HighlightType highlightType)
        {
            MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName ("MyMenu", "MyInventoryBox") as MenuInventoryBox;
            int slot = inventoryBox.GetItemSlot (invInstance);
            UnityEngine.UI.Button uiButton = inventoryBox.uiSlots [slot].uiButton;
            if (uiButton == GetComponent <UnityEngine.UI.Button>())
            {
                GetComponent <Animator>().SetTrigger ("MyTrigger");
            }
        }
    
    }
    

    This would need to be attached to each slot, which should each have Button and Animator components. You'll need to update the script's "MyTrigger" name as well to match your own.

  • Ok, I got the Inventory icons animated when using the 'Object: Highlight Inventory item' function, thanks!

    One last thing: to replicate the AC behaviour of above script, how do I achieve the following?

    dynamically set the overlay's graphic to the intended inventory item highlight texture.

    I'm using two textures per inv icon, both identical, except one has a highlighted outline. So how to switch to the Active texture?

    I suspect it has something to do with the 'Texture AC.InvItem.activeTex' class?

  • edited February 2021

    If you rely on Animation to show a RawImage that can overlay the UI Button, then you can just update the RawImage's Image field to match the activeTex texture:

    using AC;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class TriggerHighlightAnimation : MonoBehaviour
    {
    
        public RawImage rawImage;
    
        private void OnEnable () { EventManager.OnInventoryHighlight_Alt += OnInventoryHighlight; }
        private void OnDisable () { EventManager.OnInventoryHighlight_Alt -= OnInventoryHighlight; }
    
        private void OnInventoryHighlight (InvInstance invInstance, HighlightType highlightType)
        {
            MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName ("MyMenu", "MyInventoryBox") as MenuInventoryBox;
            int slot = inventoryBox.GetItemSlot (invInstance);
            UnityEngine.UI.Button uiButton = inventoryBox.uiSlots [slot].uiButton;
            if (uiButton == GetComponent <UnityEngine.UI.Button>())
            {
                rawImage.texture = invInstance.InvItem.activeTex;
                GetComponent <Animator>().SetTrigger ("MyTrigger");
            }
        }
    
    }
    
  • Sorry, I meant: a child Image (not a raw) is attached to each UI button (so I have greater control over the Rect Transform size of the inv icons, which is why I also deleted the UI button's default Image component)

    So I tested above script with only a Raw Image attached to the UI button, but it:

    • does not update to the active texture
      (or I'm not triggering it correctly in AC? it IS supposed to trigger to active texture with 'Object: Highlight Inventory item' in UI mode, correct?)

    • leaves a horrible white blank square in the inventory bar when you select that inv icon. :)
      (InventoryBox is set to Disable Object when slot is empty, but that always worked as intended)

    • AC complains if I only use a Raw Image and can't find a normal Image component for the UI button.. so I added a transparent Image to the UI button, but same outcome.

    Is it even possible to have the script update an Image component to the active cursor texture? I guess texture assignment only works with Raw Images..

    Apologies if this is becoming a Unity UI crash course. o:)

  • I think there's some confusion between us in terms of what it is you have / trying to achieve.

    The script above works by changing the texture of a RawImage that's separate to anything controlled by AC. This isn't the same component as the one used by the InventoryBox element to display the regular item - it should be a separate graphic that is overlaid on top.

    The Image component only accepts sprites, so using a RawImage means you can avoid a texture -> sprite conversion in the script.

    As this is a visual problem, I think it's best to see some images and details of exactly what it is you have, and are trying to do.

  • Ah I see, ok I'll try to explain with some of my settings / pictures.

    My inventory icons are two different sprites:
    image

    AC Active cursor FX settings:
    image

    My actionlist:
    image

    When the InventoryBox menu Source is set to AC, this produces the desired fading effect of the Active inventory graphic (with the outline).

    I am trying to achieve the same with a Unity UI prefab.
    Maybe there's an even more efficient way (without having to duplicate all my inventory sprites with an outline), by somehow copying the AC controlled cursor into a secondary overlay, but I have no idea how to do that either.

  • And what have you set up in terms of the Inventory UI?

    The active inentory FX isn't possible as a built-in feature of UI-based menus, so relying on animation/script as above is the way to go.

    The general approach is:

    1) For each item slot in the UI - create an additional RawImage on a new GameObject that occupies the same space as the item's regular graphic. Set this RawImage's alpha colour to zero, so that it's invisible by default.
    2) Attach an Animator to each, and create an Animation that controls the RawImage's alpha colour to produce the intended effect, before returning it back to zero. Wire up a Trigger parameter so that you can control it.
    3) Use a script that hooks into the OnInventoryHighlight event to first set the RawImage's texture to match the item, and then trigger the animation on the correct Animator.

  • Ok, thanks for explaining. I think I got most steps right, but still..

    My UI setup:

    image

    Animator settings:
    image

    Inv Slot1 settings:
    image
    image

    Img1 settings:
    image

    new Rawimage settings:
    image

    Normal result with AC inv:
    https://i.imgur.com/dGSzkJW.mp4

    I get this when performing all above steps:
    https://i.imgur.com/K6h2lOY.mp4

    It's hard to see with the white square behind it, but I don't see the active inventory texture being used in the Rawimage.

    Any idea what's going on?

  • edited February 2021

    What's flashing in the video? The Image or the RawImage? Pause the game when this occurs to see exactly what's what.

    Your Trigger name doesn't match that in the script - did you change it? Bear in mind that you don't need to create a separate Animator Controller / Trigger for each icon. Animations reference the objects they control by name, so you can re-use the same Animator for all icons so long as they all control an object named "RawImage".

    I can also see that the RawImage object is disabled in one of your screens. This is fine, so long as the animation clips themselves also control this state.

    How/when are you triggering the Object: Highlight Action relative to viewing the menu, and where is the script placed? You can place a Debug.Log statement inside the script function to get a message in the Console when the triggering should occur - use that method to determine if it's running but having no effect, vs running at the wrong time, vs not running at all.

    Bear in mind that the menu must be open at the time the highlight is triggered for it to register.

  • The RawImage was flashing in the video. It's correctly triggered by your script. (I updated my trigger name in your script upfront)

    The script is placed in Slot1-6 (see screenshot 4).

    The rawimage disabled in screenshot can be ignored, it's when I took an extra screenshot after experimenting some more with below step 2.

    The problem is:
    1) the 'invInstance.InvItem.activeTex' line does not update the RawImage to the Active inventory graphic I posted a screenshot off (outlined candle, as defined in AC inventory manager)
    2) when I use a combination of Image plus Rawimage in a UI Slot, the Image will permanently display a white square. Seems it can only take one of the two?

    Just to be clear: your script triggers my animation state perfectly, and adding debug.log statements only confirms that.

    It just doesn't switch to the Inventory's Active Graphic.

    btw: SUPERhelpful tip regarding re-use of Animators, VERY helpful! :)

  • I suspect that the issue is that the RawImage is being picked up by the InventoryBox element for its own use, so it's being controlled by AC as well.

    Rather than making it a child of your Slot object, make a new parent (i.e. SuperSlot) and parent both to that, i.e.:

    -> SuperSlot1
        -> Slot1 (linked to Menu)
            -> Image1 (regular item display)
        -> RawImage1 (highlight item display)
    
  • Excellent, that was exactly it!
    Required some minor tweaks, so I'll post my steps, if it can help anyone else.

    I first tried:

       ->SuperSlot1
            ->Slot1(linked to Menu)  **Animator & Highlight script attached here**
                ->Image1(regular item display)
            ->RawImage1(highlight item display)
    

    but I could not access the RawImage's property from this hierarchy level;
    apparently this is a Unity restriction on Animators

    Then:

        -> SuperSlot1  **Animator & Highlight script attached here**
            -> Slot1 (linked to Menu)
                -> Image1 (regular item display)
            -> RawImage1 (highlight item display)
    

    Both scenario's did not start the ShowHighlight animation trigger anymore.

    And finally:

        -> SuperSlot1
            -> Slot1 (linked to Menu) **Highlight script attached here**
                -> Image1 (regular item display)
            -> RawImage1 (highlight item display) **Animator attached here**
    

    I then updated the script as follows, assigned the RawImage animator to the Slot script's inspector and it works:

    using AC;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class TriggerHighlightAnimation : MonoBehaviour
    {
    
        public RawImage rawImage;
        public Animator fade;
    
        private void OnEnable() { EventManager.OnInventoryHighlight_Alt += OnInventoryHighlight; }
        private void OnDisable() { EventManager.OnInventoryHighlight_Alt -= OnInventoryHighlight; }
    
        private void OnInventoryHighlight(InvInstance invInstance, HighlightType highlightType)
        {
            MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName("Inventory", "InventoryBox") as MenuInventoryBox;
            int slot = inventoryBox.GetItemSlot(invInstance);
            UnityEngine.UI.Button uiButton = inventoryBox.uiSlots[slot].uiButton;
            if (uiButton == GetComponent<UnityEngine.UI.Button>())
            {
                rawImage.texture = invInstance.InvItem.activeTex;
                fade.Play("NameOfYourFadeAnimation");
            }
        }
    
    }
    

    Thanks so much for the excellent support! :)

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.