Forum rules - please read before posting.

Inventory property to Paramenter in Action Asset list

Short strory, I am trying to set an inventory property to an Asset Action List Parameter through script.
I add a game object )from inventory) to the scene and the end goal is to add this object's (inventory item's) properties to the parameters of the action list. (the game object itself, it's location value (integer) etc.) The linked prefab of the inventory item is set with a 3rd person camera for a closeup view so I only use properties for this.

Option 1: If I could set "Last Selected" inventory item using "Property to Parameter" I think my goal would be completed.I could then go one step Property-to-GlobalVariable and then GlobalVariable-to-Parameter. I have tried to amend the "ActionInvProperty.cs" script to handle Last Selected Inventory (as opposed to Selected Item) but not my skills are not enough. I thought I had it, but the "SetVarAsPropertyMethod" comes back as protected and I don't know how to solve that.
Option 2:I've tried my own custom action list to input propery IDs and parameter IDs to re-assign, but I don't get it right.
When running this, the parameters are not changed.
My current code, where I enter the IDs of each property and parameter is:
'''
using UnityEngine;
using System.Collections.Generic;
using UnityEditor;
namespace AC
{

[System.Serializable]
public class PropertyToParameter : Action
{

    // Declare properties here
    public override ActionCategory Category { get { return ActionCategory.Custom; }}
    public override string Title { get { return "Inventory property to Parameter"; }}
    public override string Description { get { return "Property of last selected item to a parameter."; }}


    // Declare variables here
    private GameObject gameobject;
    private int myValue;
    int currentObjectParameter;
    int selectedItemValueParameter;
    int gameObjectProperty;
    int itemValueProperty;
    public ActionListAsset myActionList;

    public override float Run ()
    {       
        if (!isRunning)
        {
            InvItem item = KickStarter.runtimeInventory.LastSelectedItem;
            InvVar myProperty1 = item.GetProperty(gameObjectProperty);
            gameobject = myProperty1.GameObjectValue;
            InvVar myProperty2 = item.GetProperty(itemValueProperty);
            myValue = myProperty2.IntegerValue;
            myActionList.GetParameter(selectedItemValueParameter).SetValue(myValue);
            myActionList.GetParameter(currentObjectParameter).SetValue(gameobject);
        }

        return 0f;
        }

    override public void ShowGUI()
    {

        currentObjectParameter = EditorGUILayout.IntField("Gl Var current object:", currentObjectParameter);
        selectedItemValueParameter = EditorGUILayout.IntField("Param ID current value:", selectedItemValueParameter);
        gameObjectProperty = EditorGUILayout.IntField("Prop ID of gameobject:", gameObjectProperty);
        itemValueProperty = EditorGUILayout.IntField("Prop ID of value:", itemValueProperty);
        myActionList = (ActionListAsset)EditorGUILayout.ObjectField("ActionList asset:", myActionList, typeof(ActionListAsset), true);

    #endif

}

'''

Long story, I have 12 hotspots A to L, and 12 objects (gameobject prefabs in inventory) AA to LL, to be place in each hotspot. I am only using the hotspots as interactions and using hotspot component varibles to store e.g. which game objecs is currently stored there, correct or not, has object or not etc.

Next step will be to return object to inventory after clicking on it, so I will also need a custom script to "add to inventory" based on inventory ID number (stored in a hotspot component variable) . Haven't started on this yet though.

Comments

  • One additional comment that may be useful. I considered 3 approaches to for this “12 objects that can go in 12 different slots” puzzle
    1. Only use the slot hotspots, current approach. Adding and removing objects to the scene and inventory. In this I am adding “item in slot” as a slot component variable. Question: does this store the prefab or the scene instance? I need the scene instance.
    2. Use both slot hotspots and object hotspots. For this I would need to store “slot number” in a component variable of the spawned object.
    3. One of the above, but instead of add/remove, use teleport to place objects. This means 12 extra objects in scene but maybe the most efficient?
  • I have tried to amend the "ActionInvProperty.cs" script to handle Last Selected Inventory (as opposed to Selected Item) but not my skills are not enough.

    This should be just a case of replacing occurences of .SelectedInstance with .LastSelectedInstance - does this give you the intended behaviour?

    I've tried my own custom action list to input propery IDs and parameter IDs to re-assign, but I don't get it right.

    Variables exposed in the ShowGUI function need to be public, so that they can be serialized.

    Question: does this store the prefab or the scene instance? I need the scene instance.

    It'd depend on the way you're assigning the variable. Could you share screenshots/details that show the workflow?

    This means 12 extra objects in scene but maybe the most efficient?

    It may be easier to manage, certainly. If the game can be saved mid-puzzle, you'd have to deal with setting up your prefabs to be spawnable via the loading process. This is possible (see the Manual's "Saving asset references" chapter), but if they're instead being teleported it's instead just a case of attaching Remember Transform components.

  • Thanks a lot!

    ActionInvProperty.cs
    I copied this script and renamed it ActionInvPropertyLastSelected, changed .SelectedInstance to .LastSelectedInstance.
    I didn't notice I had to change class names in some of the methods inside the script as well but all good now!

    Custom Action above
    I made the ShowGUI variables public, but the parameters still don't change. It's an asset based Action. I'm not sure if this impacts the way to write the custom action?
    I'd like to make this work as I will also need to work with adding/removing inventory items based on their InvID together with parameters in custom action(s).

    Prefab or Scene instance
    I believe it is the scene instance, but not sure. The problem hasn't arisen yet so best to wait and see.
    https://imgur.com/a/ZyJM6zI

    12 extra objects
    Thanks for this. Will do it with teleport.

  • Sorry, I ran into an issue directly.

    • Object A is placed in an off screen location
    • When Inventory item A is interacted with hotspot e.g. BB, I want to teleport object A to hotspot BB
    • How do I get Object A as a parameter in the "Inventory interaction with BB" action?

    Can I get the ConstantID for Object A set in the Properties of Inventory Item A in some way?

  • I set the ConstantID as one of the properties for the Inventory items.
    The below script seems to change the GameObject parameter in the Asset Action list since I add the same Action list in the ShowGUI field. But obviously it doesn't change the runtime Action List.
    Can I put some code in the AssignValues method to change the runtime Action List, or can I somehow add code to get the "Change own" behavior?

    using UnityEngine;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionPropToParam : Action
        {
    
            public override ActionCategory Category { get { return ActionCategory.Custom; } }
            public override string Title { get { return "Property to Parameter (ConstantID)"; } }
            public override string Description { get { return "Property of last selected item to a parameter."; } }
    
    
            public ActionListAsset actionListToAmend;
            GameObject gameObject;
            public int inventoryItemPropertyID;
            public int constantID;
            public int actionParameterID;
    
    
    
            public override void AssignValues(List<ActionParameter> parameters)
            {
                // gameObject = AssignFile(constantID, gameObject);
    
            }
    
            public override float Run()
            {  
                // Get the game object with the Constant ID from the inventory property
                InvItem item = KickStarter.runtimeInventory.LastSelectedItem;
                InvVar myProperty1 = item.GetProperty(inventoryItemPropertyID);
                constantID = myProperty1.IntegerValue;
                Component obj = Serializer.returnComponent<Component>(constantID);
                if (obj == null)
                {
                    Debug.LogError("GameObject with Constant ID not found!");
                    return 0f;
                }
                // Get the required component from the game object
                gameObject = obj.gameObject;
    
                // Set the parameter of the Asset Based Action List
                actionListToAmend.GetParameter(actionParameterID).SetValue(gameObject);
    
    
                return 0f;
    
            }
    
    
    
    
    #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                actionListToAmend = (ActionListAsset)EditorGUILayout.ObjectField("Action List to Amend:", actionListToAmend, typeof(ActionListAsset), false);
                inventoryItemPropertyID = EditorGUILayout.IntField("Inventory Item Property ID:", inventoryItemPropertyID);
                actionParameterID = Action.ChooseParameterGUI("Parameter ID:", parameters, actionParameterID, ParameterType.GameObject);
                if (actionParameterID < 0)
                {
                    actionParameterID = EditorGUILayout.IntField("Parameter ID:", actionParameterID);
                }
            }
    
    #endif
    
        }
    }
    
    
  • Sorry for all the posts. After hundreds of trial and errors and a bit of help from ChatGPT, I added parameters[actionParameterID].gameObject = gameObject; in the AssignValues method and it works!! All good for now...

  • Actually it didn't work.
    All it does is to set the parameters in the Asset Action List so that the next time I run it, it places the item in the hotspot that was assigned the last time I ran the action.
    "Revert to default parameters after running" does not change anything.

    How can I change the code so that I get this to work?
    I have updated the code to also include an item value from Inventory Property to be put in an Action List parameter

    I also get numerous "Null Action found. Was an Action class deleted?" error messages. I assume this is due to that some parameters are used in the action list, but not set until it is run?

    /*
     *
     *  Adventure Creator
     *  by Chris Burton, 2013-2023
     *  
     *  "ActionTemplate.cs"
     * 
     *  This is a blank action template.
     * 
     */
    
    using UnityEngine;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class PropertyToParameter : Action
        {
    
            // Declare properties here
            public override ActionCategory Category { get { return ActionCategory.Custom; }}
            public override string Title { get { return "Inventory properties to Parameters"; }}
            public override string Description { get { return "Property of last selected item to parameters."; }}
    
    
            public override void AssignValues(List<ActionParameter> parameters)
            {
                parameters[actionParameterIDgameObject].gameObject = gameObject;
                parameters[actionParameterIDValue].intValue = myValue;
    
            }
    
    
    
            // Declare variables here
            public ActionListAsset actionListToAmend;
            public GameObject gameObject;
            public int myValue =-1;
            public int inventoryItemPropertyID = -1;
            public int inventoryItemPropertyIDvalue =-1;
            public int constantID = -1;
            public int actionParameterIDgameObject = -1;
            public int actionParameterIDValue = -1;
    
            public override float Run()
            {
                if (!isRunning)
                {
                    InvItem item = KickStarter.runtimeInventory.LastSelectedItem;
                    InvVar myProperty1 = item.GetProperty(inventoryItemPropertyID);
                    constantID = myProperty1.IntegerValue;
                    Component obj = Serializer.returnComponent<Component>(constantID);
                    if (obj == null)
                    {
                        Debug.LogError("GameObject with Constant ID not found!");
                        return 0f;
                    }
                    // Get the required component from the game object
                    gameObject = obj.gameObject;
    
                    // Set the parameter of the Asset Based Action List
                    //actionListToAmend.GetParameter(actionParameterIDgameObject).SetValue(gameObject);
    
                    InvVar myProperty2 = item.GetProperty(inventoryItemPropertyIDvalue);
                    myValue = myProperty2.IntegerValue;
                    //actionListToAmend.GetParameter(actionParameterIDValue).SetValue(myValue);
                }
    
                return 0f;
            }
    
    #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                actionListToAmend = (ActionListAsset)EditorGUILayout.ObjectField("ActionList asset:", actionListToAmend, typeof(ActionListAsset), true);
                inventoryItemPropertyID = EditorGUILayout.IntField("Prop ID of gameobject:", inventoryItemPropertyID);
                actionParameterIDgameObject = Action.ChooseParameterGUI("Parameter ID:", parameters, actionParameterIDgameObject, ParameterType.GameObject);
                if (actionParameterIDgameObject < 0)
                {
                    actionParameterIDgameObject = EditorGUILayout.IntField("Parameter ID:", actionParameterIDgameObject);
                }
                inventoryItemPropertyIDvalue = EditorGUILayout.IntField("Prop ID of value:", inventoryItemPropertyIDvalue);
                actionParameterIDValue = Action.ChooseParameterGUI("Parameter ID:", parameters, actionParameterIDValue, ParameterType.Integer);
                if (actionParameterIDValue < 0)
                {
                    actionParameterIDValue = EditorGUILayout.IntField("Parameter ID:", actionParameterIDValue);
    
    
    
                }
            }
    #endif
    
        }
    
    }
    
  • Could you explain - in simple but precise terms - what you're looking to achieve? I'm not 100% clear from the code, but if you can detail the exact intended behaviour, I can see about rewriting it.

    FWIW, AC's v1.77.2 update will include a "Last Selected Item" option for the "Inventory: Property to variable" Action.

  • Hi,

    Thank you for helping!
    As simply as I can

    • 12 different items that go into 12 different slots. Only one combination is correct.
    • Inventory items A to L in inventory
    • Hotspots AA to LL in scene
    • When dropping an item to a hotspot, I want to register the following in the hotspot component variables
      • Bool CorrectHole
      • Bool HasItemInHole
      • GameObject CurrentItemInHole
        -The inventory interaction needs the following parameters
      • GameObject Item interacting with Hotspot (need to set this to the runtime Action), the ConstantID is stored as an InvItem property
      • Int ID of item interacting with Hotspot (need to set this to the runtime Action), the int ID of item is stored as an InvItem property
      • Various parameters that come from the Hotspot
    1. I need to set a gameobject based on the ConstantID in the InvItem property and assign this to a runtime Action parameter[0]
    2. I need to set the item ID in the InvItem property and assign this to the runtime Acion parameter[6]

    My current script only sets the parameters in the ActionListAsset and not in the runtime version of this asset. I tried to play around with OnBeginActionList but couldn't make it work. Sorry for the confusion.

  • edited April 2023

    Thanks for clarifying.

    Is the ActionList that contains the Action the same as the one whose parameters you wish to affect? You can set actionListToAmend automatically, if so.

    The "parameterID < 0" checks can also be removed - this is to allow the fields in the UI to themselves be parameterisable, but can be removed (at least for the moment) to simplify the code.

    Try this:

    using UnityEngine;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class PropertyToParameter : Action
        {
    
            public override ActionCategory Category { get { return ActionCategory.Custom; }}
            public override string Title { get { return "Inventory properties to Parameters"; }}
            public override string Description { get { return "Property of last selected item to parameters."; }}
    
            private ActionList actionListToAmend;
            public int inventoryItemPropertyID = -1;
            public int inventoryItemPropertyIDvalue =-1;
            public int actionParameterIDgameObject = 0;
            public int actionParameterIDValue = 6;
    
            public override void AssignParentList(ActionList actionList)
            {
                actionListToAmend = actionList;
            }
    
            public override float Run()
            { 
                InvItem item = KickStarter.runtimeInventory.LastSelectedItem;
                InvVar myProperty1 = item.GetProperty (inventoryItemPropertyID);
                int constantID = myProperty1.IntegerValue;
                Component obj = Serializer.returnComponent<Component>(constantID);
                if (obj == null)
                {
                    Debug.LogError("GameObject with Constant ID not found!");
                    return 0f;
                }
    
                GameObject gameObject = obj.gameObject;
                actionListToAmend.GetParameter (actionParameterIDgameObject).SetValue (gameObject);
    
                InvVar myProperty2 = item.GetProperty(inventoryItemPropertyIDvalue);
                int myValue = myProperty2.IntegerValue;
                actionListToAmend.GetParameter (actionParameterIDValue).SetValue(myValue);
    
                return 0f;
            }
    
            #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                inventoryItemPropertyID = EditorGUILayout.IntField("Prop ID of gameobject:", inventoryItemPropertyID);
                actionParameterIDgameObject = EditorGUILayout.IntField("GameObject Parameter ID:", actionParameterIDgameObject);
    
                inventoryItemPropertyIDvalue = EditorGUILayout.IntField("Prop ID of value:", inventoryItemPropertyIDvalue);
                actionParameterIDValue = EditorGUILayout.IntField("Value Parameter ID:", actionParameterIDValue);
            }
    
            #endif
    
        }
    
    }
    
  • This works great! Thanks a lot!!

    On a only slightly related topic, I am storing the "item in the hotspot" 's ConstantID as a component variable. This is then going into the Use: action list as a parameter.
    I want to take this parameter (containing the Constant ID), find the GameObject and put the GameObject in another parameter.

    However, the below code returns int ConstantID as the parameterID, not the value currently in the parameter.

    using UnityEngine;
    using System.Collections.Generic;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class CompVarToParameter : Action
        {
    
            public override ActionCategory Category { get { return ActionCategory.Custom; } }
            public override string Title { get { return "CompVarToParameter"; } }
            public override string Description { get { return "ConsID CompVar to GameObject Parameter"; } }
    
            private ActionList actionListToAmend;
            public int constIDparameter;
            public int currentNetsukeGameObjectParameter;
            public int constantID;
    
            public override void AssignParentList(ActionList actionList)
            {
                actionListToAmend = actionList;
            }
    
            public override float Run()
            {
    
                constantID = actionListToAmend.GetParameter(constIDparameter).intValue;
                Debug.Log(constantID);
                Component obj = Serializer.returnComponent<Component>(constantID);
                if (obj == null)
                {
                    Debug.LogError("GameObject with Constant ID not found!");
                    return 0f;
                }
    
                GameObject gameObject = obj.gameObject;
                actionListToAmend.GetParameter(currentNetsukeGameObjectParameter).SetValue(gameObject);
    
                return 0f;
            }
    
    #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                constIDparameter = EditorGUILayout.IntField("Const ID parameter slot:", constIDparameter);
                currentNetsukeGameObjectParameter = EditorGUILayout.IntField("Move Netsuke GO slot:", currentNetsukeGameObjectParameter);
            }
    
    #endif
    
        }
    
    }
    

    How can I get it to return the intvalue stored in the parameter?

  • It should be already - the Console should be printing the parameter's integer value. If it's showing the wrong value, then it could be that the value itself isn't being set properly.

    How are you setting the parameter's value?

  • edited April 2023

    Thanks for checking this.
    Please see below info:

    https://imgur.com/a/iqF3sPl

    I am also doing a similar thing to add an inventory item based on the invID stored as an int in a parameter and the same things happen. The code is in the last picture in the attached link.

    I also have two other things that I have been wanting to ask for a while but I'll put those in a separate thread.

  • edited April 2023

    Thanks.

    This is because the parameter is of the type "Component Variable" - so the intValue represents the ID of the variable it's linked to.

    To get the linked variable's value, replace:

    constantID = actionListToAmend.GetParameter(constIDparameter).intValue;
    

    with:

    constantID = actionListToAmend.GetParameter(constIDparameter).GetVariable().IntegerValue;
    
  • Great. Thanks for getting my head around Component Variables vs. Integer parameters. I wasn't sure when reading about "intValue" in the scripting guide as it mentions "The new value or ID number". All good now!!

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.