diff options
Diffstat (limited to 'Assets/Scripts')
| -rw-r--r-- | Assets/Scripts/GameControllerInput.cs | 7 | ||||
| -rw-r--r-- | Assets/Scripts/GameProgressManager.cs | 35 | ||||
| -rw-r--r-- | Assets/Scripts/GameProgressManager.cs.meta | 2 | ||||
| -rw-r--r-- | Assets/Scripts/PlayerControl.cs | 1 | ||||
| -rw-r--r-- | Assets/Scripts/PlayerMovement.cs | 29 | ||||
| -rw-r--r-- | Assets/Scripts/RandomSpawnPosition.cs | 30 | ||||
| -rw-r--r-- | Assets/Scripts/SceneStatus.cs | 20 | ||||
| -rw-r--r-- | Assets/Scripts/SceneStatus.cs.meta | 2 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/Area.cs | 39 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/Area.cs.meta | 2 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/MaskAnswers.cs | 48 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/MaskAnswers.cs.meta | 2 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/TagItem.cs | 16 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/TagPool.cs | 2 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/TaggedItemSelector.cs | 159 | ||||
| -rw-r--r-- | Assets/Scripts/Tag/TaggedItemSelector.cs.meta | 2 |
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 |
