unity库存系统插件-Ultimate Inventory System(四)自定义代码篇


前言

这篇为自定义视图代码篇,本篇会从项目的角度重新规划功能
添加删除物品的接口、数据联动(喝血药)、物品联动(与模型联动-穿戴)、捡取东西的优化、打怪爆装备的接口、加载保存接口、宝箱随机功能。


一、库存接口

1、获得库存接口

protected uint m_InventoryID = 1;
void Start(){
	var inventory = InventorySystemManager.GetInventoryIdentifier(m_InventoryID).Inventory;
}

2、获得库存总体属性(方便计算角色属性加成)

(1)通常情况人物由自身和装备属性组成,以下api可以快速获取库存内的物品属性集合

//attributeName为属性名称,例如填入“灵气”这类属性值
var inventory = InventorySystemManager.GetInventoryIdentifier(m_InventoryID).Inventory;
var sum = inventory.GetFloatSum(attributeName);

(2)获得库存中的集合类型
在这里插入图片描述

var EquipmentCollection = inventory.GetItemCollection("装备栏");
var ItemCollection1 = inventory.GetItemCollection("ItemCollection1");
EquipmentCollection.GetFloatSum(attributeName);
EquipmentCollection.GetFloatSum(attributeName);

二、物品接口

Item是一个用于引用Item实例的类。它通常存储在库存中。

///如果Item是可变的,它可以更改属性值。

///如果项是不可变的,则它只能在创建时更改其属性

1、物品

物品集合由物品堆栈列表组成。默认物品集合允许每个物品单个物品堆栈,但在多物品集合的情况下,每个物品可能有多个物品堆栈。例如,你可能有两个堆栈“5个苹果”和“10个苹果”。“苹果”物品无法区分,因为它们是相同的,但堆栈是不同的,每个堆栈都有自己的参考。因此,例如,如果您想删除“3个苹果”,您可以从“5个苹果”或“10个苹果”堆栈中选择这样做。

//创建新的物品-多种方式(显式或隐式)
new ItemInfo(itemAmount, itemCollection, itemStack);
new ItemInfo("MyItem", 1);
new ItemInfo(item, amount);
new ItemInfo(itemAmount);
new ItemInfo(itemStack);
new ItemInfo(itemAmount, otherItemInfo);
new ItemInfo(amount, otherItemInfo);
new ItemInfo(itemDefinition, amount);
new ItemInfo(otherItemInfo, amount);
new ItemInfo(amount, item);
using Opsive.UltimateInventorySystem.Core;
using Opsive.UltimateInventorySystem.Core.DataStructures;

//给指定库存添加三柄飞剑
inventory.AddItem("飞剑", 3);

//从ItemCollection2集合删除2个铁
//获得库存接口
var inventory = InventorySystemManager.GetInventoryIdentifier(m_InventoryID).Inventory;
//从ItemCollection2集合中删除
var EquipmentCollection = inventory.GetItemCollection("ItemCollection2");
//首先获取您想要的项目。在这里我们将得到我们找到的第一堆铁。
var result = EquipmentCollection.GetItemInfo(InventorySystemManager.GetItemDefinition("铁"));
//如果结果没有值,则库存中没有铁
if (result.HasValue == false) { return; }
//我们现在有了铁的ItemInfo。
var itemInfo = result.Value;
//让我们最多删除两个铁
itemInfo = new ItemInfo(Mathf.Max(2, itemInfo.Amount), itemInfo);
inventory.RemoveItem(itemInfo);

//插件提供AddItem、RemoveItem、RemoveAllItems等接口,示例略,可自行尝试

2、货币

using Opsive.UltimateInventorySystem.Core.InventoryCollections;
using Opsive.UltimateInventorySystem.Exchange;

private CurrencyOwner m_CurrencyOwner;
void Awake(){
    InventoryIdentifier inventoryIdentifier = InventorySystemManager.GetInventoryIdentifier(m_InventoryID);
    m_CurrencyOwner = inventoryIdentifier.CurrencyOwner;

	//调用
    AddCurrency("上品灵石", 20);
    RemoveCurrency("上品灵石", 10);
}

public void AddCurrency(string currencyName,int amount) 
{
    m_CurrencyOwner.AddCurrency(currencyName,amount);
}
public void RemoveCurrency(string currencyName, int amount)
{
    m_CurrencyOwner.RemoveCurrency(currencyName, amount);
}

3、获取并设置物品属性

(1)获得物品的属性

using Opsive.UltimateInventorySystem.Core.AttributeSystem;

/// <summary>
/// 打印物品的属性值
/// </summary>
/// <param name="inventory"></param>
/// <param name="itemName"></param>
/// <param name="attributeName"></param>
void GetItemAttributeValue(Inventory inventory,string itemName,string attributeName) {

    var item = GetItem(inventory,itemName);
    var value = GetItemAttributeAsObject(item, attributeName);
    Debug.Log(value);
}

/// <summary>
/// 获得物品
/// </summary>
/// <param name="inventory"></param>
/// <param name="itemName"></param>
Item GetItem(Inventory inventory,string itemName) {
    Item item;

    //获得物品定义
    ItemDefinition itemDefinition = InventorySystemManager.GetItemDefinition(itemName);
    //判空
    if (itemDefinition == null)
    {
        Debug.LogError("该系统木有这玩野:"+itemName);
    }

    //获得传入库存中与之匹配的第一个物品
    var itemInfo = inventory.GetItemInfo(itemDefinition);
    //判空
    if (itemInfo.HasValue == false)
    {
        Debug.LogError("该库存木有这玩野:" + itemName);
        //不包含,但也可以从默认物品获得属性
        item = itemDefinition.DefaultItem;
    }
    else
    {
        item = itemInfo.Value.Item;
    }
    return item;
}

/// <summary>
/// 获得物品属性
/// </summary>
/// <param name="item"></param>
/// <param name="attributeName"></param>
/// <returns></returns>
object GetItemAttributeAsObject(Item item, string attributeName)
{
    //类型未知,故而使用object
    var attribute = item.GetAttribute(attributeName);
    if (attribute == null)
    {
        Debug.LogError($"物品 '{item.name}' 木有找到名字为 '{attributeName}'的属性");
        return null;
    }
    var attributeValue = attribute.GetValueAsObject();
    return attributeValue;
}

  private float GetItemAttributeAsFloat(Item item, string attributeName)
    {
        var floatAttribute = item.GetAttribute<Attribute<float>>(attributeName);

        if (floatAttribute == null)
        {
            Debug.LogError($"物品 '{item.name}' 木有找到float类型的 '{attributeName}'的属性");
            return float.NaN;
        }

        return floatAttribute.GetValue();
    }

    private string GetItemAttributeAsString(Item item, string attributeName)
    {
        var stringAttribute = item.GetAttribute<Attribute<string>>(attributeName);

        if (stringAttribute == null)
        {
            Debug.LogError($"物品 '{item.name}' 木有找到string类型的 '{attributeName}'的属性");
            return null;
        }

        return stringAttribute.GetValue();
    }

    private void GetItemAttributeAsInt(Item item, string attributeName)
    {
        var intAttribute = item.GetAttribute<Attribute<int>>(attributeName);

        if (intAttribute == null)
        {
            Debug.LogError($"物品 '{item.name}' 木有找到int类型的 '{attributeName}'的属性");
            return;
        }

        intAttribute.GetValue();
    }

调用

//获得飞剑的属性描述并打印
var inventory = InventorySystemManager.GetInventoryIdentifier(1).Inventory;
GetItemAttributeValue(inventory, "飞剑", "描述");

(2)设置物品属性

	void SetItemAttributeValue(Inventory inventory, string itemName, string attributeName,string value) {
        var item = GetItem(inventory, itemName);
        SetItemAttributeAsObject(item , attributeName, value);

    }

    void SetItemAttributeAsObject(Item item,string attributeName,string attributeValueAsStringObject) {
        //https://opsive.com/support/documentation/ultimate-inventory-system/save-system/
        if (item.IsMutable == false)
        {
            Debug.Log("不可变物品");
            return;
        }

        var itemAttribute = item.GetAttribute(attributeName);
        if (itemAttribute == null)
        {
            Debug.Log($"物品中没有'{item.name}'属性");
            return;
        }

        if (itemAttribute.AttachedItem == null)
        {
            Debug.Log($"'{attributeName}'不是一个属性");
            return;
        }
        //不知道属性类型,用string设置
        itemAttribute.SetOverrideValueAsObject(attributeValueAsStringObject);
   }


    private void SetItemAttributeAsInt(Item item, string attributeName, int attributeValue)
    {
        var intAttribute = item.GetAttribute<Attribute<int>>(attributeName);

        if (intAttribute == null)
        {
            Debug.Log($"物品中没有int类型的'{item.name}'属性");
            return;
        }

        intAttribute.SetOverrideValue(attributeValue);
    }

    private void SetItemAttributeAsString(Item item, string attributeName, string attributeValue)
    {
        var stringAttribute = item.GetAttribute<Attribute<string>>(attributeName);

        if (stringAttribute == null)
        {
            Debug.Log($"物品中没有string类型的'{item.name}'属性");
            return;
        }

        stringAttribute.SetOverrideValue(attributeValue);
    }

    private void SetItemAttributeAsFloat(Item item, string attributeName, float attributeValue)
    {
        var floatAttribute = item.GetAttribute<Attribute<float>>(attributeName);

        if (floatAttribute == null)
        {
            Debug.Log($"物品中没有float类型的'{item.name}'属性");
            return;
        }

        floatAttribute.SetOverrideValue(attributeValue);
    }

调用

//修改飞剑的描述属性为:修改了
//如果有多把飞剑将会修改第一个,其余不变
var inventory = InventorySystemManager.GetInventoryIdentifier(1).Inventory;
SetItemAttributeValue(inventory,"飞剑","描述","修改了");

4、自定义随机物品接口

通常游戏中物品的属性是固定且稳定的,但从多年以前像暗黑破坏神之类的游戏越来越多,其中敌人有概率掉落一个具有随机稀有度和攻击属性的物品。随机攻击属性取决于稀有度,玩家不会想要攻击力低于普通物品的传奇物品。
不幸的是,这些通常需要按游戏定制。我这里提供一种写法,需要注意该类物品需要是可变的(基本属性设置为可变的,注意:要在运行时覆盖属性,该项目必须是可变且唯一的,也就是需要满足Mutable & Unique)。

代码-暂定(在进行调试和封装)

三、UI面板

第一种:

void Start(){
	var displayPanelManager = InventorySystemManager.GetDisplayPanelManager(m_InventoryID);
	displayPanelManager.OpenPanel("BagPanel");//打开背包
	//displayPanelManager.ClosePanel("BagPanel");//关闭背包
}

第二种:

public DisplayPanel BagPanel;
void Start(){
	BagPanel.SmartOpen();//打开背包
    //displayPanel.SmartClose();//关闭背包
}

四、交互(物品穿戴)

参考官方的demo场景——14 Get Set Attribute Stat (With Code),穿戴装备通过Equipper,首先需要我们把物品添加一个GameObject的属性,子类继承它并设置对应物品的预制体。

采集和丢弃在demo场景——13 Pickups,人(怪物)死后爆出装备,宝箱功能在此基础上制作即可。

五、保存加载

1、通用接口

using Opsive.UltimateInventorySystem.SaveSystem;

//因为时序问题,这里写在Start里面
void Start(){
	//保存在文件0中
  	 SaveSystemManager.Save(0, true);
     //加载到文件0中
     SaveSystemManager.Load(0);
     //删除文件0中的保存
     SaveSystemManager.DeleteSave(0);
     //输出保存路径 我的PC端为C:\Users\user\AppData\LocalLow\DefaultCompany\YYS,自行修改
     SaveSystemManager.Instance.PrintSaveFolderPath();

     //获取当前缓存的保存数据的状态
     SaveDataInfo saveDataInfo = SaveSystemManager.GetCurrentSaveDataInfo();
     //获取特定Saver组件的缓存序列化数据
     SaveSystemManager.TryGetSaveData("密钥", out var serializedData);
     Debug.Log(serializedData.Version);
}      

2、重写或者自定义
参考以下链接即可,注意新版本的ISave好像替换为InventorySaver;怎么说呢,我觉得用官方自带的接口即可,既然用这种插件就代表着处于原型开发阶段,将官方的保存接口整合到自己项目的总保存接口当中,利大于弊。
文档链接


总结

此篇有些潦草,不少功能一笔带过,实在事出有因。
插件更新(最新为1.2.16)和其他的事情耽搁,本人准备重新规划和改动该库存插件的文章;目前的篇幅带着个人主观的思想探索,不够简练,很多说明没有必要,有些则是漏掉,导致写这篇的时候感觉有不少需要补充说明,写出来必定有割裂感。综上所述,故而某些功能一概而过。

具体计划第一篇不动,第二篇丰富细节,第三篇重构精简,第四篇补全,流程会重新走一遍确保无误。(最近研究两个有意思的功能,希望5月底能补完)
新版本文章重构基本完成,官方在新版本修复了不少bug并提供了新的Demo示例,导致部分我想完善的功能没必要写了,直接看官方案例就行了。
最后我会将官方的demo和文章的demo整合精简一下,至于官方的demo整合完成后当然是删个干净。

感想

本来还想多写些,把自己想的具体需求写出来,但是重构过程中我扪心自问,这些基础够了吗?够了。够了吗?做游戏还不够!假设游戏世界中每个人都有自己的库存,可以交易,角色的属性可以通过装备的物品增强属性/改变外观,爆装备还是搜尸体,具体怎么交互,这些都需要自己实现。
而这些不是一尘不变的,需要设计师不断试错才能确定,我们没必要将自己想做的东西完整的说出来,将怎么做类似的功能告诉大家;做游戏就好比用一堆颜色不同的石子拼图,我们只需要给想做的人一堆石子并告诉她怎么拼就可以了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity建造系统件(BuildSystem)是一款非常方便的工具,它可以帮助您轻松地创建、打包和发布Unity项目。这款件不仅易于使用,而且还提供了许多有用的功能和选项,可以让您更加高效地管理项目。 首先,在Unity中导入BuildSystem件,并打开它的窗口。在这里,您可以选择要构建或打包的平台,并指定生成文件的目录和名称。您也可以选择是否为该版本应用自定义图标、版本号和构建时间戳。 此外,BuildSystem还提供了几种构建选项,例如设置是否为IL2CPP编译器生成代码、指定是否要使用增量构建,并支持并行构建等。这些选项可以大大优化构建流程,并使您更加快速地收到反馈。 最后,如果您需要在发布之前进行测试,BuildSystem还提供了一个内置的测试平台,可以让您轻松地测试您的应用程序并查看其运行情况。此外,您还可以在BuildSystem菜单中找到其他有用的功能,例如Clean选项和大量的日志信息,这些都可以帮助您更好地管理项目并优化构建流程。 总之,Unity建造系统件是一款非常有用的工具,可以极大地简化您的构建和发布流程,并提供许多有用的功能和选项,让您更加高效地管理项目。 ### 回答2: Unity建造系统件(buildsystem)是一款可帮助开发者更轻松地构建和打包游戏的工具。该件具有以下几个功能: 1.构建流程自动化:使用该件,开发者无需手动输入命令,即可自动执行构建流程,并生成构建文件。 2.多平台支持:该件可支持多种平台的游戏构建,包括PC、Mac、Linux、iOS和Android等。 3.易于配置:使用该件,开发者可通过简单的配置文件(WASM)来设置不同平台的构建参数。 4.灵活性:该件可扩展到自定义脚本,以便满足不同项目的需求。 使用该件需要遵循以下几个步骤: 1.下载并导入件:将件文件导入Unity项目,并安装在项目中。 2.创建构建配置文件:创建一个名为“build.json”的配置文件,用来定义构建需要的参数,如平台、版本等。 3.运行构建命令:在Unity控制台中执行构建命令,即可自动构建游戏,并生成相应的构建文件。 4.发布游戏:将生成的构建文件上传至目标平台的发布渠道中,以发布游戏。 总之,Unity建造系统件是一款简单实用的工具,可帮助开发者更方便地构建和发布游戏。它的多平台支持、易于配置以及灵活性,将为Unity游戏开发提供更加便利的解决方案。 ### 回答3: Unity建造系统件是一款可以优化项目构建过程的工具。该件可以简化部署操作、速度快,同时还能避免构建过程中的错误。以下是使用Unity建造系统件的指南: 1.下载和安装:在Unity Asset Store中下载和安装Unity建造系统件。 2.创建新的构建配置:选择“文件”>“建造设置”,在创建的新窗口中,选择“添加”来创建新的配置。 3.配置构建设置:为项目的选择目录指定构建方式,选择输出目录,选择场景列表,以及定义其他的高级设置。 4.开启构建过程:在“建造设置”窗口中,单击“运行”来启动构建过程。 5.查看结果:当构建完成后,查看结果。如果没有错误,你就可以在指定的输出目录中找到构建好的项目。 总的来说,Unity建造系统件可以优化项目构建,并可以增加构建结果的可靠性。如果你经常构建项目,那么该件是非常值得推荐的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值