Forum rules - please read before posting.

Hover over inventory->Description on GameObject

Hello Chris,

Did my homework and found there's another user who wanted to achieve the same result before asking you:
https://adventurecreator.org/forum/discussion/9757/examine-object-when-mouse-over-the-hotspot
I wanted to achieve the same result as averkin, but only during the inventory menu: when hovering over an item, I want to have a certain description on one place (a GameObject which is tied to a certain UI). I used the code posted by you in that thread but it didn't work for me :(

Here's what I did:

1) Created a Menu called "Item Description". Set it to "Mouse Over" as I want it when the mouse is over the item. Created an "label" element.

2) Went to Inventory and added Description property as type String

3) Went back to the menu and finished with this settings: Label type: "Inventory Property". Inventory property: "Description". Inventory Item source: "Mouse Over"

4) Created a Game Object (where I want the text to be displayed) and added the provided script.

1st problem: Not sure if this setting is the correct one.
2nd problem: i can't test it because it says: Error CS0122 'GVar.textVal' is inaccessible due to its protection level
3rd problem: I don't understand what this means "(Setting the "0" values to match your own)". It's been typed in your first response to that user.

Maaaaaaybe there's another easier way to it, but it will always will need to check which item I'm hovering over and that's AC handling it in our game.
The main objective is to display certain description to be displayed when hovering during the inventory on a certain part of the screen (gameobject).
IF! there's a way to also make it language-wise friendly, the better.

Thanks a lot!

Comments

  • It's an old script - replace ".textVal" with ".TextValue" to fix the error.

    The other thread's approach is different to the use of the "Inventory Property" label type above, though. With the script, you instead define a Global String variable that the script updates, and use the Label element to display that variable's value.

    (Setting the "0" values to match your own)

    The script needs to know which property to read, and which variable to update. Properties and variables can both be identified by their ID number, which is to the left of their names in their respective Managers. These numbers will be unique to your project, so you'd need to update the script to reflect them.

    Try without the script, however. Steps 1-3 should be enough. If you have issue, check the Console and share screenshots both of your setup and what happens at runtime.

  • Thanks a lot for the reply. I will test it in a few hours. I have a couple of questions though:
    1) We are making a multilingual game, so spanish and english are a must for us. What approach is better to link the language to the item description? The one with the "old script" or the one I put above with the 1-3 steps.

    I will continue working on this later. Thanks as always for your help.

  • Both methods involve storing the text itself inside inventory properties, which are translatable, so both can work. For a String variable or property to be translatable, just check Values can be translated? in their definition.

    To have the script work with translations, you should just need to replace:

    string invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty (invPropertyID).textVal;
    

    with:

    string invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty (invPropertyID).GetValue (Options.GetLanguage ());
    
  • Hello Chris,
    Thanks for everything above. I'm super close to making it work but I only see it on the console! :( Actually the idea is to show it in a particular place (a game object) which is the cards you can see in the screenshots (they are animated).
    I tried using a Text component and a TextMesh to replace them with the item description with no luck.

    https://imgur.com/a/JKZeGpO

    Thanks for the help. If we can replace the text with the Item Description we are done with the inventory part.

  • I don't see any Debug.Log statements in your script - where are the Console messages coming from?

    The script works by updating a Global String variable, so you'll need to make sure your Text component is linked to the Menu via a Label element so that it can display it using variable tokens.

    However, if you're attaching the script directly to the UI object you should be able to bypass that as well as that of the need for the string variable:

    GetComponent<TMPro.TextMeshProUGUI> ().text = invItemDescription; // For TMPro
    GetComponent<UnityEngine.UI.Text> ().text = invItemDescription; // For UI Text
    
  • Hello Chris,
    Unfortunately I can't make it work, with the TMPRo or the Text itself. Here's my setup.
    As for the console, I omitted in the screenshot the several debugs I put because unfortunately I'm not getting the item description pass to the Text. It's marked down there in red that it doesn't read anything.

    Any clue on why? I omitted the menu as you can see and on hovering, I still can see the details below in the console, but not passing to the Text object.

    https://imgur.com/a/wCxBcB8

    Thanks a lot!

  • Your variable-updating code is part of your OnMenuTurnOn event hook, so it'll only be called once - and at the moment the menu is being turned on.

    If you want it to be updated continually, move the code inside it to your Update function. I'd suggest doing this anyway as part of the debugging process even if that's not your final intent.

  • Hello Chris, That indeed made ir work. I will leave here the final script for future references on this matter. Thanks as always for making our life easier.

    using UnityEngine;
    using AC;
    using TMPro;

    public class InventoryItemDescription : MonoBehaviour
    {

    public int invPropertyID = 4; // Set this as appropriate
    public int stringVariableID = 7; // Set this as appropriate
    public TextMeshProUGUI inventoryText;
    public string invItemDescription;
    
    void Update()
    {
        if (KickStarter.runtimeInventory.hoverItem != null)
        {
            invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
            GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
            inventoryText.text = invItemDescription;
        }
    }
    

    }

  • Hello Chris,

    I'm getting back at you because I found an error while using this script when using two inventories together, while at the same time on scene. Let me explain briefly:

    The scene has two inventories which can be called at the same time. One is called "Clues", and the other called "People". They both use the same "variable" and but different "Inventory properties". If I hover over a Clue or a People, this line gives me an error here:

    invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty(invPropertyID).GetValue(Options.GetLanguage());

    The script is attached to each Button/GameObject. Even if I change property IDs and String Variable ID I still got the error. I also tried creating new IDs. No luck. If I delete or disable one type of Box, they work, so basically, the can't exist at the same time.

    I think for some reason when two boxes are present, they collide, hence the error.
    They are two boxes inside one "container" under AC.
    Is this normal? I can't figure out why they do this.

    Thanks

  • What is the actual error message, and is the full script as it was in your earlier post?

    As an alternative to reading hoverItem property in an Update loop, you can hook into the OnMouseOverMenu custom event which is fired when the mouse hovers over a new menu element or slot. You can then check the element's title property to determine if it's the one you want to get information about:

    void OnEnable () { EventManager.OnMouseOverMenu += OnMouseOverMenu; }
    void OnDisable () { EventManager.OnMouseOverMenu -= OnMouseOverMenu; }
    
    void OnMouseOverMenu (Menu menu, MenuElement element, int slot)
    {
        if (element.title == "MyInventory")
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance mouseOverInvInstance = inventoryBox.GetInstance (slot);
            if (InvInstance.IsValid (mouseOverInvInstance))
            {
                //
            }
        }
    }
    
  • My bad, I forgot to copy the error.

    NullReferenceException: Object reference not set to an instance of an object
    InventoryItemDescription.Update () (at XXX/Scripts/InventoryItemDescription.cs:20)

    The script is the same, yes.
    I'll give it a try then, though I would like to know why the previous one is failing on that line.
    Thanks

    public void Start()
    {
        inventoryText = GetComponent<TextMeshProUGUI>();
    }
    void Update()
    {
        if (KickStarter.runtimeInventory.hoverItem != null)
        {
            invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
            GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
            inventoryText.text = invItemDescription;
        }
    }
    
    public void DeleteTheTexts()
    {
        inventoryText.text = "";
    }
    
  • As for the second script, I also have the same Object reference error on this line:
    if (element.title == "Inventory Box Clues").

    I also tried this combination: if(element != null && element.title == "Inventory Box People") but here I have the same result as the first script (crash)

    void OnMouseOverMenu(Menu menu, MenuElement element, int slot)
    {
        if (element.title == "Inventory Box Clues")
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance mouseOverInvInstance = inventoryBox.GetInstance(slot);
            if (InvInstance.IsValid(mouseOverInvInstance))
            {
                invItemDescription = KickStarter.runtimeInventory.hoverItem.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
                GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
                inventoryText.text = invItemDescription;
            }
        }
    }
    
  • Just a little clarification. You will see that I wrote "== Clues" and "== People". That's because one script is only for Clues and the other for People. And I also tried combining script 1 and 2, one for clues and one for people, and same error.

    Little images of what we are trying to do: https://imgur.com/a/GWO7pFw

  • Your script is checking the element, and extracting the item instance that the mouse is over, but still referring to "hoverItem" to extract the property.

    You can move the title check to a string field in the Inspector, so that you can use the same script for both objects:

    public string inventoryBoxName;
    
    void OnMouseOverMenu (Menu menu, MenuElement element, int slot)
    {
        if (element != null && !string.IsNullOrEmpty (inventoryBoxName) && element.title == inventoryBoxName)
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance mouseOverInvInstance = inventoryBox.GetInstance(slot);
            if (InvInstance.IsValid (mouseOverInvInstance))
            {
                invItemDescription = mouseOverInvInstance.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
                GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
                inventoryText.text = invItemDescription;
            }
        }
    }
    
  • This works amazing! Thank you very much. With this script I was able to redo all three inventories and without any issues.
    Now, the final piece (i guess):

    how can I bring the inventory main graphic into a GameObject (specific place in the scene)?

    I want to add it to this script so I can use the same. If it's possible of course! I will paste the final script later so anyone wondering how to do a beautiful profile page with all many details, can do it. It took time, and your guidance, but we were able to do it :) Thanks a lot.

  • how can I bring the inventory main graphic into a GameObject (specific place in the scene)?

    From a given InvInstance class you can access the item's texture with:

    myInvInstance.InvItem.tex;
    

    This is a raw Texture type - not a sprite. There's a few ways you can apply it to a scene object - apply to a material, convert to a sprite, etc, but the easiest way is to rely on a RawImage component in a UI canvas:

    public string inventoryBoxName;
    public UnityEngine.UI.RawImage rawImage;
    
    void OnMouseOverMenu (Menu menu, MenuElement element, int slot)
    {
        if (element != null && !string.IsNullOrEmpty (inventoryBoxName) && element.title == inventoryBoxName)
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance mouseOverInvInstance = inventoryBox.GetInstance(slot);
            if (InvInstance.IsValid (mouseOverInvInstance))
            {
                invItemDescription = mouseOverInvInstance.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
                GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
                inventoryText.text = invItemDescription;
    
                rawImage.texture = mouseOverInvInstance.InvItem.tex;
            }
        }
    }
    

    I will paste the final script later so anyone wondering how to do a beautiful profile page with all many details, can do it

    Sounds like a great fit for the AC wiki, I'm sure it would go down well there.

  • I will paste this and many more in the Wiki. Here's the full script. It works flawlessly.

    using UnityEngine;
    using AC;
    using TMPro;

    public class InventoryItemDescription : MonoBehaviour
    {
    public int invPropertyID = 2; // Set this as appropriate
    public int stringVariableID = 7; // Set this as appropriate
    public TextMeshProUGUI inventoryText;
    public string invItemDescription;
    public string inventoryBoxName;
    public bool imageNeeded;
    public UnityEngine.UI.RawImage rawImage;

    void OnEnable()
    {
        EventManager.OnMouseOverMenu += OnMouseOverMenu;
    }
    
    void OnDisable()
    {
        EventManager.OnMouseOverMenu -= OnMouseOverMenu;
    }
    
    void OnMouseOverMenu(Menu menu, MenuElement element, int slot)
    {
        if (element != null && !string.IsNullOrEmpty(inventoryBoxName) && element.title == inventoryBoxName)
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance mouseOverInvInstance = inventoryBox.GetInstance(slot);
            if (InvInstance.IsValid(mouseOverInvInstance))
            {
                invItemDescription = mouseOverInvInstance.GetProperty(invPropertyID).GetValue(Options.GetLanguage());
                GlobalVariables.SetStringValue(stringVariableID, invItemDescription);
                inventoryText.text = invItemDescription;
                if (imageNeeded)
                {
                    rawImage.texture = mouseOverInvInstance.InvItem.tex;
                }
            }
        }
    }
    

    }

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.