Forum rules - please read before posting.

Replacing the item cursor texture through code

edited December 2022 in Technical Q&A

Hi there!

"Return to Monkey Island" surprised me with a nice feature I'd like to replicate:
When dragging an item over a hotspot (and that item/hotspot combo isn't supported) - the inventory item on the cursor is replaced by a texture indicating that this can't be done.
I found it quite nifty how this saves the player from listening to a bunch of unnecessary "I can't do that" prompts.

I found the right time and conditions for when to do it, but I can't figure out how to actually swap the texture:

EventManager.OnHotspotSelect += (Hotspot hotspot) =>
{
    if (KickStarter.runtimeInventory.SelectedItem == null)
        return;

    bool hasInteraction = false; // I know how to get the correct value here
    if (!hasInteraction)
    {
        // Todo: Replace the inventory item texture of the cursor with a "not doable" icon
        KickStarter.cursorManager.pointerIcon.ReplaceTexture(newTexture);
    }
};

Comments

  • With AC v1.76.1, you can assign an override texture to an item at runtime without affecting the fields in the Inventory Manager. To set the selected item's texture, it'd be a case of:

    KickStarter.runtimeInventory.SelectedInstance.Tex = newTexture;
    

    The approach I'd probably try myself, however, would be to use a Unity UI cursor. That way, an Animator's Bool parameter could then be controlled through script, and used to hide/show an overlay texture on top of the cursor instead of replacing it.

  • There's no Text prop on SelectedInstance, but I managed to switch out the texture using:
    KickStarter.runtimeInventory.SelectedInstance.CursorIcon.texture = newTexture;

    Any ideas as to reset it back to the original texture on OnHotspotDeselect? I tried getting hold of it on EventManager.OnInventorySelect_Alt, but I'm not sure how to get a reference to the texture being used on the cursor, these are all null at that point:

    EventManager.OnInventorySelect_Alt += (invCollection, invInstance) =>
    {
        Debug.Log(KickStarter.runtimeInventory.SelectedInstance.CursorIcon.texture);
        Debug.Log(invInstance.InvItem.selectedTex);
        Debug.Log(invInstance.InvItem.cursorIcon.texture);
    };
    

    The approach I'd probably try myself, however, would be to use a Unity UI cursor. That way, an Animator's Bool parameter could then be controlled through script, and used to hide/show an overlay texture on top of the cursor instead of replacing it.

    I'm not sure how that works and I find the current cursor solution works great except for this one feature. Maybe it's something you would consider implementing for an upcoming release, or implement an API to simplify swapping out (or showing an image on top of) the dragged cursor texture?

  • I'm not sure how to get a reference to the texture being used on the cursor, these are all null at that point

    Can you share a screenshot showing the item's properties within the Inventory Manager?

  • Here you go:
    https://1drv.ms/u/s!Amz_vh8OYDX3vspMxsumrM_UWsGdcg?e=ycHj5u

    Interesting that you have an optional cursor icon there, maybe I should be grabbing the main graphics texture somehow?

  • The CursorIcon property you're accessing through script has no assigned texture in its asset - this is the optional cursor field you're mentioning.

    You can assign the texture with:

    CursorIcon.ReplaceTexture (myTexture);
    

    When set, this will override the default texture assigned in the "Main graphic" field. Reverting back should just be a case of passing null to the ReplaceTexture function.

  • Yes, that works πŸ‘

    Now. I'd like to do the same thing for indicating whether a combine items interaction is possible, but AC doesn't seem to expose an event for when hovering an item over another item, or am I just not seeing it?

    Thanks

  • Not for that specific hover situation, but there is a general-purpose OnMouseOverMenu event, whose parameters can be used to filter out unwanted calls:

    private void OnEnable () { EventManager.OnMouseOverMenu += OnMouseOverMenu; }
    private void OnDisable () { EventManager.OnMouseOverMenu -= OnMouseOverMenu; }
    
    private void OnMouseOverMenu (AC.Menu _menu, MenuElement _element, int _slot)
    {
        if (InvInstance.IsValid (KickStarter.runtimeInventory.SelectedInstance) && _element != null && _element is MenuInventoryBox)
        {
            MenuInventoryBox inventoryBox = _element as MenuInventoryBox;
            InvInstance hoverInstance = inventoryBox.GetInstance (_slot);
            if (InvInstance.IsValid (hoverInstance))
            {
                // Hover over item with another selected
            }
        }
    }
    
  • edited December 2022

    OK, so the OnMouseOverMenu covers the Select event, but I still need a matching event to cover Deselect, so I can set the cursor back to null.

    Also, I notice that for some reason, OnMouseOverMenu get erroneously triggered when I drag an item above or below my (Unity UI) inventory list. It doesn't happen when I drag the item to the left or right of the inventory list. The parameters for these event calls are the same as when the event is called when the mouse is over an inventory item.

  • A brute-force approach is to read the value of RuntimeInventory.HoverInstance each frame:

    private InvInstance lastFrameHoverInstance;
    
    private void LateUpdate ()
    {
        if (KickStarter.runtimeInventory.HoverInstance != lastFrameHoverInstance)
        {
            lastFrameHoverInstance = KickStarter.runtimeInventory.HoverInstance;
            if (!InvInstance.IsValid (KickStarter.runtimeInventory.SelectedInstance)) return;
    
            if (InvInstance.IsValid (lastFrameHoverInstance))
            {
                // Begin hover
            }
            else
            {
                // End hover
            }
        }
    }
    
  • I see, yeah. Thank you for coming up with that solution, but as you imply, it seems like a pretty heavy handed way of reaching the goal.

    Would you consider adding events for the start and stop of hovering over items with another item in a future AC release?

    It would be crazy appreciated - having this work not only for item/hotspots combos, but also for item/item combos gets rid of ALL the pesky "I can't do that"/"that doesn't seem to work" messages that has been plaguing our favorite genre for way too long :)

    Thanks

  • I will consider it, yes.

  • Much appreciated! Don't hesitate to reach out if you need help testing the feature or need to bounce any detail surrounding itπŸ‘

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.