summaryrefslogtreecommitdiff
path: root/Assets/Scripts
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts')
-rw-r--r--Assets/Scripts/GameControllerInput.cs7
-rw-r--r--Assets/Scripts/GameProgressManager.cs35
-rw-r--r--Assets/Scripts/GameProgressManager.cs.meta2
-rw-r--r--Assets/Scripts/PlayerControl.cs1
-rw-r--r--Assets/Scripts/PlayerMovement.cs29
-rw-r--r--Assets/Scripts/RandomSpawnPosition.cs30
-rw-r--r--Assets/Scripts/SceneStatus.cs20
-rw-r--r--Assets/Scripts/SceneStatus.cs.meta2
-rw-r--r--Assets/Scripts/Tag/Area.cs39
-rw-r--r--Assets/Scripts/Tag/Area.cs.meta2
-rw-r--r--Assets/Scripts/Tag/MaskAnswers.cs48
-rw-r--r--Assets/Scripts/Tag/MaskAnswers.cs.meta2
-rw-r--r--Assets/Scripts/Tag/TagItem.cs16
-rw-r--r--Assets/Scripts/Tag/TagPool.cs2
-rw-r--r--Assets/Scripts/Tag/TaggedItemSelector.cs159
-rw-r--r--Assets/Scripts/Tag/TaggedItemSelector.cs.meta2
16 files changed, 385 insertions, 11 deletions
diff --git a/Assets/Scripts/GameControllerInput.cs b/Assets/Scripts/GameControllerInput.cs
index ff29c12..7472463 100644
--- a/Assets/Scripts/GameControllerInput.cs
+++ b/Assets/Scripts/GameControllerInput.cs
@@ -24,4 +24,11 @@ public class GameControllerInput : MonoBehaviour
bool isGrabbing = value > 0.5f;
_playerControl.grabbing = isGrabbing;
}
+
+ public void OnBoost(InputAction.CallbackContext context)
+ {
+ float value = context.ReadValue<float>();
+ bool isBoost = value > 0.5f;
+ _playerControl.boosting = isBoost;
+ }
}
diff --git a/Assets/Scripts/GameProgressManager.cs b/Assets/Scripts/GameProgressManager.cs
new file mode 100644
index 0000000..463e2b3
--- /dev/null
+++ b/Assets/Scripts/GameProgressManager.cs
@@ -0,0 +1,35 @@
+using Tag;
+using UnityEngine;
+
+[RequireComponent(typeof(SceneStatus))]
+public class GameProgressManager : MonoBehaviour
+{
+ public MaskAnswers player1;
+ public MaskAnswers player2;
+
+ public SceneStatus sceneStatus;
+
+ private void Awake()
+ {
+ sceneStatus = GetComponent<SceneStatus>();
+ }
+
+ public void Refresh()
+ {
+ if (player1.bindPlayer != null &&
+ player2.bindPlayer != null &&
+ SceneStatus.Instance.current == Status.Waiting)
+ {
+ // 开始游戏
+ sceneStatus.current = Status.Playing;
+ OnGameStart();
+ }
+ }
+
+ private void OnGameStart()
+ {
+ Debug.Log("开始游戏!");
+ player1.bindPlayer.GetComponent<PlayerMovement>().enabled = true;
+ player2.bindPlayer.GetComponent<PlayerMovement>().enabled = true;
+ }
+}
diff --git a/Assets/Scripts/GameProgressManager.cs.meta b/Assets/Scripts/GameProgressManager.cs.meta
new file mode 100644
index 0000000..7dfacf2
--- /dev/null
+++ b/Assets/Scripts/GameProgressManager.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 17eb712b2ed01264c9221deb269a625e \ No newline at end of file
diff --git a/Assets/Scripts/PlayerControl.cs b/Assets/Scripts/PlayerControl.cs
index 3ef3dc8..85f753c 100644
--- a/Assets/Scripts/PlayerControl.cs
+++ b/Assets/Scripts/PlayerControl.cs
@@ -5,4 +5,5 @@ public class PlayerControl : MonoBehaviour
public float movementHorizontal;
public float movementVertical;
public bool grabbing;
+ public bool boosting;
}
diff --git a/Assets/Scripts/PlayerMovement.cs b/Assets/Scripts/PlayerMovement.cs
index 90252b3..add03ba 100644
--- a/Assets/Scripts/PlayerMovement.cs
+++ b/Assets/Scripts/PlayerMovement.cs
@@ -1,15 +1,21 @@
-using System;
using UnityEngine;
[RequireComponent(typeof(PlayerControl))]
[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : MonoBehaviour
{
- public float movementSpeed;
- public float movementSpeedOnGrabbing;
+ private static readonly float BoostAccel = 10;
+ public float movementSpeed = 5;
+ public float movementSpeedOnGrabbing = 3;
+ public float boostFalloffLerp = 0.025f;
+
private PlayerControl _playerControl;
private Rigidbody _rigidbody;
+
+ private float _currentBoost;
+
+ private bool CanBoost => _currentBoost <= 0.1f;
private void Awake()
{
@@ -17,15 +23,25 @@ public class PlayerMovement : MonoBehaviour
_rigidbody = GetComponent<Rigidbody>();
}
+ private void Update()
+ {
+ if (_playerControl.boosting && CanBoost)
+ {
+ _currentBoost = BoostAccel;
+ }
+ }
+
private void FixedUpdate()
{
FixedUpdateMovement();
+
+ FixedUpdateBoostFalloff();
}
private void FixedUpdateMovement()
{
var velocity = _rigidbody.linearVelocity;
- var speed = _playerControl.grabbing ? movementSpeedOnGrabbing : movementSpeed;
+ var speed = _playerControl.grabbing ? movementSpeedOnGrabbing : movementSpeed + _currentBoost;
var direction = new Vector3(
_playerControl.movementHorizontal,
0,
@@ -34,4 +50,9 @@ public class PlayerMovement : MonoBehaviour
var playerVelocity = speed * direction + velocity.y * Vector3.up;
_rigidbody.linearVelocity = playerVelocity;
}
+
+ private void FixedUpdateBoostFalloff()
+ {
+ _currentBoost = Mathf.Lerp(_currentBoost, 0, boostFalloffLerp);
+ }
}
diff --git a/Assets/Scripts/RandomSpawnPosition.cs b/Assets/Scripts/RandomSpawnPosition.cs
index cc8b92e..334d72d 100644
--- a/Assets/Scripts/RandomSpawnPosition.cs
+++ b/Assets/Scripts/RandomSpawnPosition.cs
@@ -1,16 +1,34 @@
-using System;
using UnityEngine;
-using Random = UnityEngine.Random;
public class RandomSpawnPosition : MonoBehaviour
{
- public float range = 3;
+ private PlayerMovement _playerMovement;
+
+ private void Awake()
+ {
+ _playerMovement = GetComponent<PlayerMovement>();
+ }
private void Start()
{
- var x = Random.Range(-range, range);
- var z = Random.Range(-range, range);
+ Debug.Log("等待设备输入以加入玩家...");
- transform.position = new Vector3(x,transform.position.y,z);
+ var binder = FindFirstObjectByType<GameProgressManager>();
+ if (binder.player1.bindPlayer == null)
+ {
+ binder.player1.bindPlayer = _playerMovement;
+ var targetPos = binder.player1.transform.position;
+ transform.position = targetPos;
+ Debug.Log("玩家1已加入");
+ binder.Refresh();
+ }
+ else if (binder.player2.bindPlayer == null)
+ {
+ binder.player2.bindPlayer = _playerMovement;
+ var targetPos = binder.player2.transform.position;
+ transform.position = targetPos;
+ Debug.Log("玩家2已加入");
+ binder.Refresh();
+ }
}
}
diff --git a/Assets/Scripts/SceneStatus.cs b/Assets/Scripts/SceneStatus.cs
new file mode 100644
index 0000000..30ca2d2
--- /dev/null
+++ b/Assets/Scripts/SceneStatus.cs
@@ -0,0 +1,20 @@
+using System;
+using UnityEngine;
+
+public class SceneStatus : MonoBehaviour
+{
+ public static SceneStatus Instance;
+
+ private void Awake()
+ {
+ Instance = this;
+ }
+
+ public Status current;
+}
+
+[Serializable]
+public enum Status
+{
+ Waiting, Playing
+}
diff --git a/Assets/Scripts/SceneStatus.cs.meta b/Assets/Scripts/SceneStatus.cs.meta
new file mode 100644
index 0000000..5a4b0a8
--- /dev/null
+++ b/Assets/Scripts/SceneStatus.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: b68daba43a5f8684b9fbdd7d2b247767 \ No newline at end of file
diff --git a/Assets/Scripts/Tag/Area.cs b/Assets/Scripts/Tag/Area.cs
new file mode 100644
index 0000000..196bd36
--- /dev/null
+++ b/Assets/Scripts/Tag/Area.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Tag
+{
+ public class Area : MonoBehaviour
+ {
+ public ItemType itemAccepted;
+ public List<TagItem> items;
+
+ private void OnTriggerEnter(Collider other)
+ {
+ if (other.CompareTag("Part"))
+ {
+ var obj = other.GetComponent<TagItem>();
+ if (obj.info.itemType == itemAccepted)
+ {
+ if (! items.Contains(obj))
+ {
+ items.Add(obj);
+ }
+ }
+ }
+ }
+
+ private void OnTriggerExit(Collider other)
+ {
+ if (other.CompareTag("Part"))
+ {
+ var obj = other.GetComponent<TagItem>();
+ if (items.Contains(obj))
+ {
+ items.Remove(obj);
+ }
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/Tag/Area.cs.meta b/Assets/Scripts/Tag/Area.cs.meta
new file mode 100644
index 0000000..1faee20
--- /dev/null
+++ b/Assets/Scripts/Tag/Area.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 495019f9357aaff04b03214dd604b5b8 \ No newline at end of file
diff --git a/Assets/Scripts/Tag/MaskAnswers.cs b/Assets/Scripts/Tag/MaskAnswers.cs
new file mode 100644
index 0000000..f8e5583
--- /dev/null
+++ b/Assets/Scripts/Tag/MaskAnswers.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Tag
+{
+ public class MaskAnswers : MonoBehaviour
+ {
+ public PlayerMovement bindPlayer;
+ public Area eyeArea;
+ public Area norseArea;
+ public Area mouseArea;
+ public Area elbowArea;
+ public Area accessoriesArea;
+
+ public Answer CollectToAnswer()
+ {
+ var totalTag = new List<string>();
+
+ foreach (var areaItem in eyeArea.items)
+ {
+ foreach (var t in areaItem.info.tags)
+ totalTag.Add(t);
+ }
+ foreach (var areaItem in norseArea.items)
+ {
+ foreach (var t in areaItem.info.tags)
+ totalTag.Add(t);
+ }
+ foreach (var areaItem in mouseArea.items)
+ {
+ foreach (var t in areaItem.info.tags)
+ totalTag.Add(t);
+ }
+ foreach (var areaItem in elbowArea.items)
+ {
+ foreach (var t in areaItem.info.tags)
+ totalTag.Add(t);
+ }
+ foreach (var areaItem in accessoriesArea.items)
+ {
+ foreach (var t in areaItem.info.tags)
+ totalTag.Add(t);
+ }
+
+ return new Answer(totalTag.ToArray());
+ }
+ }
+}
diff --git a/Assets/Scripts/Tag/MaskAnswers.cs.meta b/Assets/Scripts/Tag/MaskAnswers.cs.meta
new file mode 100644
index 0000000..6f91e25
--- /dev/null
+++ b/Assets/Scripts/Tag/MaskAnswers.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 2b048de9cb06a25ba843bc01f0729b49 \ No newline at end of file
diff --git a/Assets/Scripts/Tag/TagItem.cs b/Assets/Scripts/Tag/TagItem.cs
index 837eb3f..27b5efe 100644
--- a/Assets/Scripts/Tag/TagItem.cs
+++ b/Assets/Scripts/Tag/TagItem.cs
@@ -5,5 +5,21 @@ namespace Tag
public class TagItem : MonoBehaviour
{
public TaggedItemInfo info;
+ public SpriteRenderer spriteRenderer;
+
+ public static void CleanTagItem()
+ {
+ foreach (var i in FindObjectsByType<TagItem>(FindObjectsSortMode.None))
+ {
+ if (i.info == null)
+ Destroy(i.gameObject);
+ }
+ }
+
+ private void OnEnable()
+ {
+ if (info == null) return;
+ spriteRenderer.sprite = info.image;
+ }
}
}
diff --git a/Assets/Scripts/Tag/TagPool.cs b/Assets/Scripts/Tag/TagPool.cs
index 75bd0fc..e6109fd 100644
--- a/Assets/Scripts/Tag/TagPool.cs
+++ b/Assets/Scripts/Tag/TagPool.cs
@@ -5,6 +5,6 @@ namespace Tag
{
public class TagPool : MonoBehaviour
{
- public List<TaggedItemInfo> items = new();
+ public List<TagItem> items = new();
}
}
diff --git a/Assets/Scripts/Tag/TaggedItemSelector.cs b/Assets/Scripts/Tag/TaggedItemSelector.cs
new file mode 100644
index 0000000..0179bf4
--- /dev/null
+++ b/Assets/Scripts/Tag/TaggedItemSelector.cs
@@ -0,0 +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
diff --git a/Assets/Scripts/Tag/TaggedItemSelector.cs.meta b/Assets/Scripts/Tag/TaggedItemSelector.cs.meta
new file mode 100644
index 0000000..bbe62e0
--- /dev/null
+++ b/Assets/Scripts/Tag/TaggedItemSelector.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: a3c64c11fc0f4b9b698b811d2051db1a \ No newline at end of file