重做物品系统
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 物品库存
|
||||
/// </summary>
|
||||
public class Inventory {
|
||||
/// <summary> 背包容量 </summary>
|
||||
public int capacity;
|
||||
/// <summary> 插槽列表 </summary>
|
||||
public List<InventorySlot> slots;
|
||||
/// <summary> 改变事件 </summary>
|
||||
public event Action<Inventory> OnChange;
|
||||
|
||||
/// <summary> 物品库存 </summary>
|
||||
public Inventory(int capacity) {
|
||||
this.capacity = capacity;
|
||||
IEnumerable<int> enumerable = Enumerable.Range(0, capacity);
|
||||
slots = enumerable.Select(_ => new InventorySlot()).ToList();
|
||||
}
|
||||
|
||||
/// <summary> 应用修改 </summary>
|
||||
public void Apply() => OnChange?.Invoke(this);
|
||||
/// <summary> 遍历数组 </summary>
|
||||
public void ForEach(Action<InventorySlot> action) => slots.ForEach(action);
|
||||
/// <summary> 获取一个空插槽 </summary>
|
||||
public InventorySlot Empty() => slots.FirstOrDefault(s => s.item == null);
|
||||
/// <summary> 相同堆叠插槽 </summary>
|
||||
public List<InventorySlot> Stackable(InventoryItem item) => slots.Where(slot => slot.IsStackable(item)).ToList();
|
||||
|
||||
/// <summary> 添加物品 </summary>
|
||||
public void AddItem(InventoryItem item, int count) {
|
||||
// 合并重复可堆叠
|
||||
int remain = MergeToSlots(item, count);
|
||||
// 如果还有剩余,按照MaxStack分批放入空位
|
||||
if (remain > 0) { AddToSlots(item, remain, true); }
|
||||
OnChange?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary> 合并到插槽 </summary>
|
||||
public int MergeToSlots(InventoryItem item, int count) {
|
||||
// 查询所有可合并的插槽
|
||||
var sameSlots = Stackable(item);
|
||||
// 合并到已有插槽
|
||||
sameSlots.ForEach(obj => obj.Settings(ref count));
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary> 添加物品 </summary>
|
||||
public void AddToSlots(InventoryItem item, int count, bool isWhile) {
|
||||
// 取一个空插槽
|
||||
InventorySlot emptySlot = Empty();
|
||||
// 没有空插槽则退出
|
||||
if (emptySlot == null) { return; }
|
||||
// 堆叠数量 = Min(物品数量 , 最大堆叠数量)
|
||||
int addCount = Mathf.Min(count, item.stack);
|
||||
// 计算剩余物品数量
|
||||
int remain = count - addCount;
|
||||
// 填充进空插槽
|
||||
emptySlot.Settings(item, addCount);
|
||||
// 没有剩余或者不循环则退出
|
||||
if (remain == 0 || !isWhile) { return; }
|
||||
// 还有余量循环执行添加
|
||||
AddToSlots(item, remain, isWhile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 299fd3a7463d8ef46ab2221eca3eeae7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 库存物品
|
||||
/// </summary>
|
||||
public class InventoryItem {
|
||||
/// <summary> 堆叠数量 </summary>
|
||||
public int stack = 1;
|
||||
/// <summary> 名字 </summary>
|
||||
public string name;
|
||||
/// <summary> 类型 </summary>
|
||||
public string type;
|
||||
/// <summary> 图片 </summary>
|
||||
public Sprite sprite;
|
||||
/// <summary> 预制件 </summary>
|
||||
public Transform prefabs;
|
||||
|
||||
/// <summary> 是否可堆叠 </summary>
|
||||
public virtual bool IsStackable(InventoryItem item) {
|
||||
return name == item.name && type == item.type && stack > 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 427a33328910b764b9014f337267f950
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 库存插槽
|
||||
/// </summary>
|
||||
public class InventorySlot {
|
||||
/// <summary> 数量 </summary>
|
||||
public int count;
|
||||
/// <summary> 名字 </summary>
|
||||
public string name;
|
||||
/// <summary> 物品 </summary>
|
||||
public InventoryItem item;
|
||||
/// <summary> 限制类型 </summary>
|
||||
public List<string> limits = new List<string>();
|
||||
|
||||
/// <summary> 图片 </summary>
|
||||
public Sprite Sprite => item != null ? item.sprite : null;
|
||||
/// <summary> 堆叠数量 </summary>
|
||||
public int MaxStack => item != null ? item.stack : 0;
|
||||
|
||||
/// <summary> 添加物品数量 </summary>
|
||||
public virtual void Settings(ref int count) {
|
||||
// 剩余容量
|
||||
int canAdd = MaxStack - count;
|
||||
// 剩余容量和余数取最小值
|
||||
int addCount = Mathf.Min(canAdd, count);
|
||||
this.count += addCount;
|
||||
count -= addCount;
|
||||
}
|
||||
/// <summary> 设置物品 </summary>
|
||||
public virtual void Settings(InventoryItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
}
|
||||
/// <summary> 替换物品 </summary>
|
||||
public virtual (InventoryItem, int) Replace(InventoryItem item, int count) {
|
||||
int remain = this.count; this.count = count;
|
||||
InventoryItem old = this.item; this.item = item;
|
||||
return (old, remain);
|
||||
}
|
||||
|
||||
/// <summary> 验证类型 </summary>
|
||||
public bool Verify(InventoryItem item) {
|
||||
string[] types = item.type.Split("/");
|
||||
return limits.All(item => types.Contains(item));
|
||||
}
|
||||
/// <summary> 是否可堆叠 </summary>
|
||||
public virtual bool IsStackable(InventoryItem obj) {
|
||||
return item != null && item.IsStackable(obj) && count < MaxStack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddb28431ab55e034386cfe8f66c0d9f5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user