Forum rules - please read before posting.

Weird use of parameters - possible?

Hi,

I am looking at using parameters to dictate the usual stuff in Action List assets - add inventory items, remove the object in the game world etc.
However the other thing I'm hoping to do is to change an image that appears on a popup menu to match the Active texture of the inventory item I feed in as a parameter. That way, I don't need to go through and manually set each one through script, but rather just feed the Inventory Item into the actionlist and have the event system do the rest!

I figured I'd hook into my OnMenuTurnOn event for the overlay/popup that asks the player whether they want to grab the item, then change the menu graphic's texture with the texture of the inventory item by referencing it from the actionlist that caused the menu to pop up.

How would I go about grabbing that reference? I checked out the wiki and was fiddling around with the GetParameter function, but I'm a little unclear on how to specifically refer to the inventory Item parameter, especially from whichever actionlist I ran to open the menu - if that's at all possible.

Hope that made sense, and please let me know if there is a blatantly easier way to change up the popup image in such a way that I don't have to go through and set each one up manually!

Cheers.

Comments

  • edited May 2021

    So long as you know the name or ID number of the inventory item parameter, you can retrieve it with GetParameter, i.e.:

    ActionParameter parameter = actionList.GetParameter ("Item");
    int itemID = parameter.intValue;
    InvItem invItem = KickStarter.runtimeInventory.GetItem (itemID);
    Texture itemTexture = invItem.tex;
    

    However, since you're dealing with ActionLists / parameters, it's also possible to create a custom Action in which you can plug the same parameter:

    using UnityEngine;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionInventoryTexture : Action
        {
    
            public int parameterID = -1;
            public int itemID;
            public string menuName;
            public string elementName;
    
    
            public override ActionCategory Category { get { return ActionCategory.Custom; }}
            public override string Title { get { return "Inventory"; }}
            public override string Description { get { return "Update menu texture."; }}
    
    
            public override void AssignValues (List<ActionParameter> parameters)
            {
                itemID = AssignInteger (parameters, parameterID, itemID);
            }
    
    
            public override float Run ()
            {
                InvItem invItem = KickStarter.inventoryManager.GetItem (itemID);
                MenuGraphic menuGraphic = PlayerMenus.GetElementWithName (menuName, elementName) as MenuGraphic;
                menuGraphic.SetNormalGraphicTexture (invItem.tex);
                return 0f;
            }
    
    
            #if UNITY_EDITOR
    
            public override void ShowGUI (List<ActionParameter> parameters)
            {
                parameterID = Action.ChooseParameterGUI ("Item ID:", parameters, parameterID, ParameterType.InventoryItem);
                if (parameterID < 0)
                {
                    itemID = EditorGUILayout.IntField ("Item ID:", itemID);
                }
                menuName = EditorGUILayout.TextField ("Menu name:", menuName);
                elementName = EditorGUILayout.TextField ("Element name:", elementName);
            }
    
            #endif
    
        }
    
    }
    

    Install this Action as ActionInventoryTexture.cs, and it'll appear in lists as the Inventory: Update menu texture Action.

  • Chris! You're a legend - I hadn't even considered writing custom actions!
    Haha this will make it 10 times less fiddly than what I'd been messing about with!

  • I implemented the above action, but was running into the issue where the override float wasn't returning a value - am I right in assuming that if I request it to return 0f, that would let it run once and carry on with the rest of the actionlist?
    I'm fairly new to ovveride functions, especially ones that actually return stuff!

  • edited May 2021

    one other question, but how would I go about using a string property to load an image from resources instead? I figured It would be easier to have a bunch of sprites there and just use them whenever I need a close up to free up the inventory item's associated textures for things like displaying whether they're equipped or not.

    I Tried:

    InvItem invItem = KickStarter.inventoryManager.GetItem(itemID);
    MenuGraphic menuGraphic = PlayerMenus.GetElementWithName(menuName, elementName) as MenuGraphic;
    string imageLocation = invItem.GetProperty(4).TextValue;
    Sprite sprite = Resources.Load<Sprite>(imageLocation);
    Texture texture = sprite.texture;
    menuGraphic.SetNormalGraphicTexture(texture);
    return 0f;
    

    and having "ItemCloseupSprites/Pistol_Image" as a string property for example (with the quote marks and without.) to no avail. it returns Null.
    Am I using "TextValue" wrong, or putting quotes in the wrong place or something?

    I can get it to print the contents of the property with a button press on a temporary script, and it does so correctly - displaying whatever is written in there, which would imply Textvalue is the right thing to use, but I can't seem to grab the image I want from resources.
    I wasn't sure if I should save the files as PNG instead of sprites, but using sprites would, I imagine, remove the need to convert them during the Resources.Load function right?

  • I implemented the above action, but was running into the issue where the override float wasn't returning a value

    Apologies - I missed that. The Run function's return value should be the length of time that the ActionList should wait before calling it again. Return zero to have the Action run once and move on.

    I've updated the script above with the correct value.

    how would I go about using a string property to load an image from resources instead?

    Don't use quotes, but start with putting your asset in the Resources folder directly so that you only need a text value of Pistol_Image.

    AC Graphic elements require a Texture asset, not a sprite. Leave your asset as a Texture type, and then try assigning the texture variable directly in the SetNormalGraphic function.

  • Sweet, thanks for that - I managed to get an image displaying, for some reason though, it will always default to the texture I’ve hooked up to item(0) though. Seems to be some kind of issue with the way the parameters load into my action perhaps?
    I tested it with both loading resources and using the active texture and both disregard the parameter for the inventory item.
    In the same action list asset, I switch out the descriptions of the item too (I have a subtitle run that says “you picked up the (x)” with x being dictated by a string parameter. As well as an action that gives you said item, and another that takes a game object in the scene as a parameter.
    These work fine however so I wonder if the script is skipping the override that determines which item I am wanting to use, perhaps.

    As an aside, one thing I noticed is that if I have the object in the scene get removed, any further actions that use parameters fed into the action list asset (from the initial action list attached to the hotspot) will drop off.
    I imagine this is because the hotspot that kicks off the initial action list is attached to the item that gets removed, so a workaround I’ve used is to teleport it behind the camera until the very end of the action list asset, before removing it.
  • Hey, thought I'd run this code by you as my solution:

        public override void AssignValues(List<ActionParameter> parameters)
        {
            //itemID = AssignInteger(parameters, parameterID, itemID);
    
            ActionParameter parameter = GetParameterWithID(parameters, parameterID);
            if (parameter != null && parameter.parameterType == ParameterType.InventoryItem)
            {
                InvItem invItem = KickStarter.inventoryManager.GetItem(parameter.intValue);
                if (invItem != null)
                {
                    itemID = invItem.id;
                }
            }
    
        }
    

    Might be overkill, but seems to work so far - I couldn't quite figure out an easier way to get the parameter to spit out its value in order to assign one to "itemID' without first grabbing the parameter, then the invItem it refers to!

  • Oh dear - I'm afraid I made yet another mistake in my sample code.

    The AssignInventory function, rather than AssignInteger, can be used to get the item ID value from an Inventory Item parameter ID:

    itemID = AssignInvItemID (parameters, invParameterID, itemID);
    
  • Thanks Chris! You gave me enough to get it all sorted anyway - but assign inventory certainly makes it cleaner!
    I’ll probably have another question for you regarding limited inventory playing nicely with stackable items but I’ll see if I can get it all sorted, and it might be better off in its own thread anyway in case people want to achieve similar.
    Once again though, thank you so much for your amazing 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.