diff options
Diffstat (limited to 'Assets')
| -rw-r--r-- | Assets/Scenes/PlayScene.unity | 73 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/TaggedItemSelector.cs | 152 |
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 |
