summaryrefslogtreecommitdiff
path: root/Assets
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-01-31 20:40:13 +0800
committer魏曹先生 <1992414357@qq.com>2026-01-31 20:40:13 +0800
commit7f95248dff152152c7892c4ea27475cac9984c06 (patch)
tree084c1d683927db02584e86f3e056221610c09933 /Assets
parent74a4f421b436b5950e52660ba7d6ebc53a818fa5 (diff)
完成TAG选择器
Diffstat (limited to 'Assets')
-rw-r--r--Assets/Scenes/PlayScene.unity73
-rw-r--r--Assets/Scripts/Tag/TaggedItemSelector.cs152
2 files changed, 222 insertions, 3 deletions
diff --git a/Assets/Scenes/PlayScene.unity b/Assets/Scenes/PlayScene.unity
index 6160f84..2487402 100644
--- a/Assets/Scenes/PlayScene.unity
+++ b/Assets/Scenes/PlayScene.unity
@@ -862,6 +862,74 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 663eeaf5f927f973cb00d1a828312f29, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Tag.TagItem
+--- !u!1 &612163277
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 612163278}
+ - component: {fileID: 612163279}
+ m_Layer: 0
+ m_Name: TagSelector
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &612163278
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 612163277}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &612163279
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 612163277}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a3c64c11fc0f4b9b698b811d2051db1a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::Tag.TaggedItemSelector
+ infos:
+ - {fileID: 11400000, guid: 06bb9506400a538b886e16eb94841c37, type: 2}
+ - {fileID: 11400000, guid: 18465dd910937128fbff39a005508825, type: 2}
+ - {fileID: 11400000, guid: 1bb764545308a4c8986ba7cb53ae936c, type: 2}
+ - {fileID: 11400000, guid: 2a2c77a7e05827431a0dd8c5f8f4a150, type: 2}
+ - {fileID: 11400000, guid: 347d315185e822330913db78e1b50ef9, type: 2}
+ - {fileID: 11400000, guid: 4f2c57569f66db0cd92da1c867c01e45, type: 2}
+ - {fileID: 11400000, guid: 587e56cbf197e9dd291e195775f4d4d6, type: 2}
+ - {fileID: 11400000, guid: 596cc7071f150fd159bcf214db6d32e2, type: 2}
+ - {fileID: 11400000, guid: 649726557df257d3c8107074f519f39e, type: 2}
+ - {fileID: 11400000, guid: 7495de039125ef9dbbd8f468a28701df, type: 2}
+ - {fileID: 11400000, guid: 77654915c1e67b6f6b90ce561c245365, type: 2}
+ - {fileID: 11400000, guid: 84846eccee30cd202b48e637bcdcc268, type: 2}
+ - {fileID: 11400000, guid: 8f6fc697e145b034eb038c5375f9c1cb, type: 2}
+ - {fileID: 11400000, guid: 99e57d72c9c6642e3afdb7391b46b69e, type: 2}
+ - {fileID: 11400000, guid: a8484d5c5e2ab0c888c9c480e746e4fb, type: 2}
+ - {fileID: 11400000, guid: bd8953a7441468d808d4f65b68407591, type: 2}
+ - {fileID: 11400000, guid: d1e651252de104cba914ec8760a52445, type: 2}
+ - {fileID: 11400000, guid: ec6a215340535b2a1b3696c7f0ab8a3a, type: 2}
+ minEyeCount: 3
+ minElbowCount: 3
+ minNorseCount: 2
+ minMouseCount: 2
+ minAccessoriesCount: 4
--- !u!1001 &613918063
PrefabInstance:
m_ObjectHideFlags: 0
@@ -3639,7 +3707,7 @@ GameObject:
- component: {fileID: 2133701600}
- component: {fileID: 2133701601}
m_Layer: 0
- m_Name: TagPool
+ m_Name: PartPool
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -3830,11 +3898,12 @@ SceneRoots:
- {fileID: 1495789857}
- {fileID: 1976095978}
- {fileID: 1181544170}
- - {fileID: 2133701600}
- {fileID: 1387273479}
- {fileID: 5902804708968422387}
- {fileID: 251165853}
- {fileID: 803179636}
+ - {fileID: 2133701600}
+ - {fileID: 612163278}
- {fileID: 134977221}
- {fileID: 1880362399}
- {fileID: 1023414505}
diff --git a/Assets/Scripts/Tag/TaggedItemSelector.cs b/Assets/Scripts/Tag/TaggedItemSelector.cs
index 87a563e..0179bf4 100644
--- a/Assets/Scripts/Tag/TaggedItemSelector.cs
+++ b/Assets/Scripts/Tag/TaggedItemSelector.cs
@@ -1,9 +1,159 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
namespace Tag
{
public class TaggedItemSelector : MonoBehaviour
{
+ public List<TaggedItemInfo> infos;
+ public TagPool pool;
+ public int minEyeCount = 3;
+ public int minElbowCount = 3;
+ public int minNorseCount = 2;
+ public int minMouseCount = 2;
+ public int minAccessoriesCount = 4;
+
+ private void Start()
+ {
+ }
+
+ public List<TaggedItemInfo> FilterByQuestion(Question question)
+ {
+ // 1. 先按类型分组
+ var groupedByType = infos.GroupBy(info => info.itemType)
+ .ToDictionary(g => g.Key, g => g.ToList());
+
+ // 2. 计算每种类型需要的最小数量
+ var minCounts = new Dictionary<ItemType, int>
+ {
+ { ItemType.Eye, minEyeCount },
+ { ItemType.Elbow, minElbowCount },
+ { ItemType.Norse, minNorseCount },
+ { ItemType.Mouse, minMouseCount },
+ { ItemType.Accessories, minAccessoriesCount }
+ };
+
+ // 3. 先收集Need中每个tag需要的数量
+ var tagRequirements = new Dictionary<string, int>();
+ foreach (var tag in question.Need)
+ {
+ if (tagRequirements.ContainsKey(tag))
+ tagRequirements[tag]++;
+ else
+ tagRequirements[tag] = 1;
+ }
+
+ // 4. 筛选结果列表
+ var result = new List<TaggedItemInfo>();
+ var usedItems = new HashSet<TaggedItemInfo>();
+
+ // 5. 先满足Need中的tag要求
+ foreach (var tagRequirement in tagRequirements)
+ {
+ var tag = tagRequirement.Key;
+ var requiredCount = tagRequirement.Value;
+ var foundCount = 0;
+
+ // 遍历所有未使用的物品,查找包含该tag的物品
+ var availableItems = infos.Where(info =>
+ !usedItems.Contains(info) &&
+ info.tags.Contains(tag))
+ .ToList();
+
+ // 按照类型优先级排序,确保每个类型都有机会被选中
+ availableItems = availableItems.OrderBy(item =>
+ {
+ var typeCount = result.Count(i => i.itemType == item.itemType);
+ var minForType = minCounts[item.itemType];
+ return typeCount >= minForType ? 1 : 0; // 优先选择未达到最小数量的类型
+ }).ThenBy(item => item.itemType)
+ .ToList();
+
+ // 选取所需数量的物品
+ for (int i = 0; i < Mathf.Min(availableItems.Count, requiredCount); i++)
+ {
+ var item = availableItems[i];
+ result.Add(item);
+ usedItems.Add(item);
+ foundCount++;
+ }
+
+ // 如果没有找到足够的物品,尝试从已满足其他tag的物品中寻找
+ if (foundCount < requiredCount)
+ {
+ var additionalItems = result.Where(item =>
+ item.tags.Contains(tag) &&
+ result.Count(i => i == item) == 1) // 确保不重复计数
+ .ToList();
+
+ // 如果一个物品有多个需要的tag,它可以被计数多次
+ // 但在这个实现中,我们保持简单,每个物品只计算一次
+ }
+ }
+
+ // 6. 确保每个类型达到最小数量
+ foreach (var typeGroup in result.GroupBy(item => item.itemType))
+ {
+ var type = typeGroup.Key;
+ var currentCount = typeGroup.Count();
+ var minRequired = minCounts[type];
+
+ if (currentCount < minRequired)
+ {
+ // 从该类型的未使用物品中补充
+ var typeItems = groupedByType.ContainsKey(type) ?
+ groupedByType[type] : new List<TaggedItemInfo>();
+
+ var unusedItemsOfType = typeItems
+ .Where(item => !usedItems.Contains(item))
+ .Take(minRequired - currentCount)
+ .ToList();
+
+ foreach (var item in unusedItemsOfType)
+ {
+ result.Add(item);
+ usedItems.Add(item);
+ }
+ }
+ }
+
+ // 7. 处理NoNeed:移除含有NoNeed标签的物品
+ if (question.NoNeed != null && question.NoNeed.Any())
+ {
+ result = result.Where(item =>
+ !item.tags.Any(tag => question.NoNeed.Contains(tag)))
+ .ToList();
+ }
+
+ // 8. 如果某个类型的最小数量仍然不满足,尝试用其他物品替换
+ foreach (var type in Enum.GetValues(typeof(ItemType)).Cast<ItemType>())
+ {
+ var currentCount = result.Count(item => item.itemType == type);
+ var minRequired = minCounts[type];
+
+ if (currentCount < minRequired)
+ {
+ // 尝试从该类型的未使用物品中获取更多
+ var typeItems = groupedByType.ContainsKey(type) ?
+ groupedByType[type] : new List<TaggedItemInfo>();
+
+ var unusedItemsOfType = typeItems
+ .Where(item => !usedItems.Contains(item))
+ .Take(minRequired - currentCount)
+ .ToList();
+
+ foreach (var item in unusedItemsOfType)
+ {
+ result.Add(item);
+ usedItems.Add(item);
+ }
+ }
+ }
+
+ return result;
+ }
}
-}
+} \ No newline at end of file