Playmaker Has item with definition action request

I'm fairly sure that Meshes are Unity Objects so it should work.
Just to make sure, try using some other Object.
 
The fsm works correctly if I set the mesh variable manually, but the Get Set Item Attribute Value Object returns the mesh variable from the item definition as null every time.
 

Attachments

  • get set mesh bug.png
    get set mesh bug.png
    268.9 KB · Views: 5
I'm looking at the code right now, I think I know why its not working.
GetSetItemAttributeValueObject expects an Attribute<Object> and not an Attribute<T> where T is an Object. So it can't find Attribute<Mesh>
Unfortunatly that's how it was designed so there is nothing we can change on UIS side that will help that.

Fortunatly there are two easy solutions
1) Use a Attribute<Object> instead of Attribute<Mesh> for your attributes. And then add another action to convert Object to Mesh (I wouldn't go that route)
or
2) Write a custom GetSetItemAttributeValueMesh (And do the same for any other Object type).
It's super easy simply create a new script and copy paste GetSetItemAttributeValueObject and replace Object by Mesh everywhere.

Code:
[HutongGames.PlayMaker.Tooltip("Get or Set an attribute value.")]
[ActionCategory("Ultimate Inventory System")]
public class GetSetItemAttributeValueMesh : GetSetItemAttributeValueBase
{
    [HutongGames.PlayMaker.Tooltip("The Value Which contains the value retrieved or contains the value to set.")]
    [UIHint(UIHint.Variable)]
    public FsmObject m_Value;
    
    protected override void DoGetSetAttributeValue(Item item)
    {
        var attribute = item.GetAttribute<Attribute<Mesh>>(m_AttributeName.Value);
        if (attribute == null) {
            Fsm.Event(m_FailEvent);
            return;
        }
        if (m_SetValue.Value) {
            attribute.SetOverrideValue(m_Value.Value as Mesh);
        } else {
            m_Value.Value = attribute.GetValue();
        }
        
        Fsm.Event(m_SuccessEvent);
    }
    protected override void DoGetAttributeValue(ItemDefinition itemDefinition)
    {
        var attribute = itemDefinition.GetAttribute<Attribute<Mesh>>(m_AttributeName.Value);
        if (attribute == null) {
            Fsm.Event(m_FailEvent);
            return;
        }
        
        m_Value.Value = attribute.GetValue();
        Fsm.Event(m_SuccessEvent);
    }
    /// <summary>
    /// Reset the public variables.
    /// </summary>
    public override void Reset()
    {
        base.Reset();
        m_Value = null;
    }
}
 
I made this action to get the name from an item definition and thought i'd share it for anyone else using playmaker

[HutongGames.PlayMaker.Tooltip("Get an item name from the item definition.")] [ActionCategory("Ultimate Inventory System")] public class GetItemName : GetSetItemAttributeValueBase { [HutongGames.PlayMaker.Tooltip("The Value Which contains the value retrieved or contains the value to set.")] [UIHint(UIHint.Variable)] public FsmString m_Value; protected override void DoGetSetAttributeValue(Item item) { var name = item.name; if (name == null) { Fsm.Event(m_FailEvent); return; } Fsm.Event(m_SuccessEvent); } protected override void DoGetAttributeValue(ItemDefinition itemDefinition) { var name = itemDefinition.name; if (name == null) { Fsm.Event(m_FailEvent); return; } m_Value.Value = name; Fsm.Event(m_SuccessEvent); } /// <summary> /// Reset the public variables. /// </summary> public override void Reset() { base.Reset(); m_Value = null; } }
 
Can you add a playmaker action Get Item Attribute that returns an array? I tried this one but I cant seem to just switch out the variable type on this one, I want to access the array of itemdefinitions that my wood barrel can drop
 

Attachments

  • UIS array.png
    UIS array.png
    99.4 KB · Views: 2
This is not exactly what you asked for but it should give you more freedom.
Instead of using ItemDefinition[] you could use ItemDefinitionAmounts and choose whether or not to use the amount value

Code:
[HutongGames.PlayMaker.Tooltip("Get or Set an attribute value.")]
    [ActionCategory("Ultimate Inventory System")]
    public class GetSetItemAttributeValueItemDefinitionAmounts : GetSetItemAttributeValueBase
    {
        [HutongGames.PlayMaker.Tooltip("The Value Which contains the value retrieved or contains the value to set.")]
        [UIHint(UIHint.Variable)]
        [ArrayEditor(VariableType.Object)]
        public FsmArray m_ItemDefinitionsValue;
        [HutongGames.PlayMaker.Tooltip("The Value Which contains the value retrieved or contains the value to set.")]
        [UIHint(UIHint.Variable)]
        [ArrayEditor(VariableType.Int)]
        public FsmArray m_AmountsValue;
        
        protected override void DoGetSetAttributeValue(Item item)
        {
            var attribute = item.GetAttribute<Attribute<ItemDefinitionAmounts>>(m_AttributeName.Value);

            if (attribute == null) {
                Fsm.Event(m_FailEvent);
                return;
            }

            if (m_SetValue.Value) {

                if (m_ItemDefinitionsValue.Values.Length != m_AmountsValue.Values.Length) {
                    Fsm.Event(m_FailEvent);
                    return;
                }

                var array = new ItemDefinitionAmount[m_ItemDefinitionsValue.Values.Length];
                for (int i = 0; i < array.Length; i++) {
                    array[i] = new ItemDefinitionAmount(m_ItemDefinitionsValue.Values[i] as ItemDefinition, (int)m_AmountsValue.Values[i]);
                }

                var itemDefinitionAmounts = new ItemDefinitionAmounts(array);
                
                attribute.SetOverrideValue(itemDefinitionAmounts);
            } else {
                var itemDefinitionAmounts = attribute.GetValue();

                m_ItemDefinitionsValue.Resize(itemDefinitionAmounts.Count);
                m_AmountsValue.Resize(itemDefinitionAmounts.Count);

                for (int i = 0; i < itemDefinitionAmounts.Count; i++) {
                    m_ItemDefinitionsValue.Set(i, itemDefinitionAmounts[i].ItemDefinition);
                    m_AmountsValue.Set(i, itemDefinitionAmounts[i].Amount);
                }
            }
            
            Fsm.Event(m_SuccessEvent);
        }

        protected override void DoGetAttributeValue(ItemDefinition itemDefinition)
        {
            var attribute = itemDefinition.GetAttribute<Attribute<ItemDefinitionAmounts>>(m_AttributeName.Value);

            if (attribute == null) {
                Fsm.Event(m_FailEvent);
                return;
            }

            var itemDefinitionAmounts = attribute.GetValue();

            m_ItemDefinitionsValue.Resize(itemDefinitionAmounts.Count);
            m_AmountsValue.Resize(itemDefinitionAmounts.Count);

            for (int i = 0; i < itemDefinitionAmounts.Count; i++) {
                m_ItemDefinitionsValue.Set(i, itemDefinitionAmounts[i].ItemDefinition);
                m_AmountsValue.Set(i, itemDefinitionAmounts[i].Amount);
            }

            Fsm.Event(m_SuccessEvent);
        }

        /// <summary>
        /// Reset the public variables.
        /// </summary>
        public override void Reset()
        {
            base.Reset();
            m_ItemDefinitionsValue = null;
            m_AmountsValue = null;
        }
    }
 
I tried it, the action will only take an Item Definitions Value of Array Type: Object, Object Type: Object.

I tried changing line 16 to [ArrayEditor(VariableType.Unknown)]
to allow me to set my ItemDefArray Array Type: Object, Object Type: ItemDefinition in the action dropdown, but it returns a null array at runtime
 

Attachments

  • itemdef array.png
    itemdef array.png
    81.6 KB · Views: 5
Unfortunatly I believe that's a limitation of Playmaker, I'm not sure what I could do to solve it.
Perhaps contact the Player Maker devs to see if they have a solution for you
 
I got it to work!

[HutongGames.PlayMaker.Tooltip("Get an attribute Array value.")] [ActionCategory("Ultimate Inventory System")] public class GetItemAttributeArrayValueItemDefinition : GetSetItemAttributeValueBase { [HutongGames.PlayMaker.Tooltip("The Value Which contains the value retrieved or contains the value to set.")] [UIHint(UIHint.Variable)] public FsmObject m_Value; [HutongGames.PlayMaker.Tooltip("The Index to get")] public FsmInt m_Index; [HutongGames.PlayMaker.Tooltip("Get random item definition from array")] public FsmBool m_Random; protected override void DoGetSetAttributeValue(Item item) { int i = m_Index.Value; bool random = m_Random.Value; Attribute<ItemDefinition[]> attributes = item.GetAttribute<Attribute<ItemDefinition[]>>(m_AttributeName.Value); if (attributes == null) { Fsm.Event(m_FailEvent); return; } else { ItemDefinition[] attributesArray = attributes.GetValue(); if (random == true) { System.Random rnd = new System.Random(); int length = attributesArray.Length; i = rnd.Next(0, length); m_Index = i; } ItemDefinition attribute = (ItemDefinition)attributesArray.GetValue(i); m_Value.Value = attribute; } Fsm.Event(m_SuccessEvent); } protected override void DoGetAttributeValue(ItemDefinition itemDefinition) { int i = m_Index.Value; bool random = m_Random.Value; var attributes = itemDefinition.GetAttribute<Attribute<ItemDefinition[]>>(m_AttributeName.Value); if (attributes == null) { Fsm.Event(m_FailEvent); return; } ItemDefinition[] attributesArray = attributes.GetValue(); if (random == true) { System.Random rnd = new System.Random(); int length = attributesArray.Length; i = rnd.Next(0, length); m_Index = i; } ItemDefinition attribute = (ItemDefinition)attributesArray.GetValue(i); m_Value.Value = attribute; Fsm.Event(m_SuccessEvent); } /// <summary> /// Reset the public variables. /// </summary> public override void Reset() { base.Reset(); m_Value = null; } }
 
Last edited:
Hello again, I am trying to make an action that returns an item definition from an inventory. I have an inventory that has only one item and I want to get the item definition for the fsm on the same object.

This is what I got so far, I'm having a difficult time understanding how to use item info to get the itemdefinition



Code:
        public void DoGetItemDefinition()
        {
         
            if (m_Inventory == null)
            {
                Debug.LogWarning("The Inventory does not exist on the gameobject", m_PrevGameObject);
                Fsm.Event(m_FailEvent);
                return;
            }
            var itemCollection = m_Inventory.GetItemCollection(m_ItemCollectionPurpose);
            if (itemCollection != null)
            {
                // NEED HELP HERE: var itemInfo = itemCollection.GetItemInfo();
                // get item definition from item collection or inventory or itemInfo
                // set item definition to itemDefinition
            }
            else
            {
                Fsm.Event(m_FailEvent);
                return;
            }
                if (itemDefinition != null)
                {
                    ItemDefinition itemDef = itemDefinition;
                    m_Value.Value = itemDef;
                    Fsm.Event(m_SuccessEvent);
                }
                else
                {
                    Fsm.Event(m_FailEvent);
                }
        }
 
Last edited:
Code:
var itemDefinition = itemInfo.Item?.ItemDefinition;

The '?' is just in case the Item is null. This way it won't give you an error, instead it will set itemDefinition to null.

You can find more examples in the documentation:
 
Top