Change the attributes of an item

fukada

Member
I am trying to change the attributes of an item by referring to the sample script below.
I am trying to set the number of times it can be acquired and create a library.

var attackAttribute = item.GetAttribute<Attribute<int>>("Attack");

I don't know how to set "item".

The samples often don't explain "item" and I can't solve it on one page, so I think it's unhelpful.

1. Change the variable of an item that has not been acquired.
2. Change the item in the inventory.

Can you tell me how to do this?

// Retrieves an attack attribute value by getting its attribute.
var attackAttribute = item.GetAttribute<Attribute<int>>("Attack");
if (attackAttribute != null) {
// The real attack value.
var myAttack = attackAttribute.GetValue();
// The override attack value.
var myAttackOverride = attackAttribute.OverrideValue;
// The inherited attack value.
var myAttackInherited = attackAttribute.GetInheritedValue();
}
I was able to create a new item and change its variables.
But perhaps since you can't change the variables of an item you already own,
the only option is to create a new one and replace it?

This causes problems if you want to give the item the number of times it has been obtained as an attribute.

public void ItemStatusChange()
{

// アイテム定義からアイテムを作成
var item = InventorySystemManager.GetItemDefinition("Ami"); //アミ(普通)
if (item == null)
{
Debug.LogError("Item definition not found.");
return;
}
else
{
Debug.Log("Item " + item);
}

var ami = InventorySystemManager.CreateItem(item);
if (ami == null)
{
Debug.LogError("Failed to create item.");
return;
}

Debug.Log("ItemGet: " + ami);


// アイテムの属性値を取得
var attackAttribute = ami.GetAttribute<Attribute<int>>("Attack");

if (attackAttribute == null)
{
Debug.LogError("Attack attribute not found.");
return;
}

if (!item.IsMutable)
{
// Immutable items cannot have their attribute set.
return;
}

if (attackAttribute != null)
{
// 実際の攻撃値。
var currentAttack = attackAttribute.GetValue();
// オーバーライド攻撃値。
var myAttackOverride = attackAttribute.OverrideValue;
// 継承された攻撃値。
var myAttackInherited = attackAttribute.GetInheritedValue();


var newValue = myAttackOverride ++; //Not added
attackAttribute.SetOverrideValue(newValue);

inventory.AddItem(ami, 1);


Debug.Log(
"実際の攻撃値: " + currentAttack +
" オーバーライド攻撃値: " + myAttackOverride +
" 継承された攻撃値: " + myAttackInherited
);
}
}

I'm sorry if I'm not good at English and I use rude language.
 
Sorry for the delay, I was out on vacation.

To get the "Item" you have to call the GetItemInfo(..) function. you'll find some examples on this page:

you can pass in an item definition as the paramenter. Example:
sword = InventorySystemManager.GetItemDefinition("Sword");

You can get the "item" from itemInfo.Item

So to recap the steps are:

1. Get the item definition
2. Get the ItemInfo using the item definition
3. Get the item from the itemInfo
4. Get the attribute on the item
5. Set the attribute on the item
 
Thank you very much for your thoughtful reply.
It is very helpful.
There are many shortcomings, and we apologize for the inconvenience, but we would appreciate your cooperation.

I was able to change the item's attributes. Thank you.

My next question is,
Is there a system for saving attributes?
I couldn't find an explanation.

The script below seems to work, is there a mistake?

namespace Opsive.UltimateInventorySystem.Demo.CharacterControl
{
using System;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers;
using Opsive.UltimateInventorySystem.Core;
using Opsive.UltimateInventorySystem.Core.InventoryCollections;
using Opsive.UltimateInventorySystem.Core.AttributeSystem;


public class PlayerStatsSaver : Saver
{
[Serializable]
public class ItemOverrideData
{
public string itemName;
public int numberOfUses; // NumberOfUses の値を保存する
public int possession; // Possession の値を保存する
}

[Serializable]
public class Data
{
public string Ex_String;
public int PlayerHP;
public List<ItemOverrideData> items;
}


public override string RecordData()
{
var data = new Data();

GameObject Player = GameObject.FindWithTag("Player");
PlayMakerFSM fsm = PlayMakerFSM.FindFsmOnGameObject(Player, "PlayerStats");
data.PlayerHP = fsm.FsmVariables.GetFsmInt("PlayerHp").Value;
data.Ex_String = "レベルアップデータ";

data.items = new List<ItemOverrideData>();

// Get all ItemCategories, Item Definitions and Items in the game.
// var allItemCategories = InventorySystemManager.ItemCategoryRegister.GetAll();
// var allItemDefinitions = InventorySystemManager.ItemDefinitionRegister.GetAll();
// var allItems = InventorySystemManager.ItemRegister.GetAll();

// システム内のアイテム変数を取得
var allItemDefinitions = InventorySystemManager.ItemDefinitionRegister.GetAll();

Debug.Log("allItemDefinitions " + allItemDefinitions);

foreach (var itemDefinition in allItemDefinitions)
{
var itemOverrideData = new ItemOverrideData
{
itemName = itemDefinition.name,
numberOfUses = itemDefinition.GetAttribute<Attribute<int>>("NumberOfUses").GetValue(), // NumberOfUses を取得して保存する
possession = itemDefinition.GetAttribute<Attribute<int>>("Possession").GetValue() // Possession を取得して保存する
};

// ここで他の属性も取得し、必要なデータを itemOverrideData に追加することができます。

data.items.Add(itemOverrideData);
}

return SaveSystem.Serialize(data);
}

public override void ApplyData(string s)
{
if (string.IsNullOrEmpty(s)) return;
var data = SaveSystem.Deserialize<Data>(s);
if (data == null) return;


// データの読み込み
GameObject Player = GameObject.FindWithTag("Player");
PlayMakerFSM fsm = PlayMakerFSM.FindFsmOnGameObject(Player, "PlayerStats");
fsm.FsmVariables.GetFsmInt("PlayerHp").Value = data.PlayerHP;

// データの適用
foreach (var itemOverrideData in data.items)
{
// 各アイテム変数の処理
// 例:アイテム変数の NumberOfUses と Possession の値を適用する
var itemDefinition = InventorySystemManager.GetItemDefinition(itemOverrideData.itemName);
if (itemDefinition != null)
{
itemDefinition.GetAttribute<Attribute<int>>("NumberOfUses").SetOverrideValue(itemOverrideData.numberOfUses);
itemDefinition.GetAttribute<Attribute<int>>("Possession").SetOverrideValue(itemOverrideData.possession);
}
}
}
}
}
 
Last edited:
I duplicated items and added them to my inventory. They are set as unique items.
However, the added items have the same value.
Please tell me how to make them have individual numerical values.

I looked through past forums about custom components, etc., but there was no clear answer.

public void OriginalNewItemGet()
{
// Retrieve the item definition
var itemDefinition = InventorySystemManager.GetItemDefinition("山太郎ガネ小(オス)");
if (itemDefinition == null)
{
Debug.LogError("Item definition not found.");
return;
}

// Create a new item from the definition
var newItem = InventorySystemManager.CreateItem(itemDefinition);
if (newItem == null)
{
Debug.LogError("Failed to create item.");
return;
}

// Get the attribute to change
var changedAttribute = newItem.GetAttribute<Attribute<int>>("NumberOfUses");
if (changedAttribute == null)
{
Debug.LogError("NumberOfUses attribute not found.");
return;
}

// Ensure the item is mutable before setting the attribute
if (!itemDefinition.IsMutable)
{
Debug.LogError("Item is immutable.");
return;
}

// Set a unique value for the attribute
var randomInt = Random.Range(1, 20);
changedAttribute.SetOverrideValue(randomInt);

// Add the new item to the inventory
m_Inventory.AddItem(newItem, 1);

Debug.Log("Created unique item with NumberOfUses: " + randomInt);
}
 
Item Attributes are automatlically saved when using the InventorySaver component and the InventorySystemManagerItemSaver components.
Learn more here:


You don't have to create a custom saver for those.


Looking at both your scripts I think the issue is that you have set your attribute as an ItemDefinition attribute. This is shared between items.
If you want to edit attributes at runtime unique to each item they must be set a Item Attributes.
Check those out:


 
Thank you very much. I was able to do it thanks to your instructions.
I have one question: how can I display a list of system items?

I can't use INVENTORYGRID or similar, so do I have to make it myself?
 
Why can you not use InventoryGrid?

If you haven't done so yet make sure you have a look at all the feature demos. We have one called "1_1 Inventory List". Is that what you need?
 
Sorry, my explanation didn't make it clear.
I want to display a list of items in the created system, not in any inventory.

I'd like to have a documentation page so that players can view unclaimed and acquired items.
A filter will also be needed.
 
Humm...

Why not make an Inventory for that documentation page. And add all the items in the game inside it. Then use that to show the documentation page?

If you really don't want an inventory for this then there are other options:

I recommend making a custom ItemViewSlotsContainer component. From there you can display your items however you want, no limitations.
You can loop over all the items in the game and check if the play has acquired them.
 
Back
Top