diff --git a/Assets/CONTENT/FEATURES/PipeJunk/Config.meta b/Assets/CONTENT/FEATURES/PipeJunk/Config.meta new file mode 100644 index 0000000..598bd0c --- /dev/null +++ b/Assets/CONTENT/FEATURES/PipeJunk/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bb903df62880440f80782f53ec0f6692 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset new file mode 100644 index 0000000..321f9fa --- /dev/null +++ b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset @@ -0,0 +1,30 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 142c75ae48de4c7ba6fd0daad6905872, type: 3} + m_Name: ItemPipeConfig + m_EditorClassIdentifier: + spawnInterval: 0.05 + spawnCooldown: 10 + localVelocityChange: {x: 0, y: -5, z: 0} + guaranteedItems: + - prefab: {fileID: 4504260422113134419, guid: 8790cd6f776403940ac664c5db12dab4, type: 3} + amount: 1 + randomItemCount: 7 + randomItems: + - prefab: {fileID: 2474374521670934351, guid: c91d2337125ccaf45a0c57af9a6703c8, type: 3} + weight: 1 + - prefab: {fileID: 4728426142119307488, guid: 795e138cd804c7c42aa508895e6a61df, type: 3} + weight: 1 + - prefab: {fileID: 4504260422113134419, guid: 8790cd6f776403940ac664c5db12dab4, type: 3} + weight: 3 + randomSpawnX: 1 + randomSpawnZ: 1 diff --git a/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset.meta b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset.meta new file mode 100644 index 0000000..65dac6c --- /dev/null +++ b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3883e23238f84f748e616770b66fa885 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs new file mode 100644 index 0000000..64069e8 --- /dev/null +++ b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[CreateAssetMenu( + fileName = "ItemPipeConfig", + menuName = "Fort Bo/Pipe Junk/Item Pipe Config")] +public sealed class ItemPipeConfig : ScriptableObject +{ + [Serializable] + public sealed class GuaranteedItem + { + public GameObject prefab; + + [Min(1)] + public int amount = 1; + } + + [Serializable] + public sealed class RandomItem + { + public GameObject prefab; + + [Min(0f)] + public float weight = 1f; + } + + [Header("Timing")] + [SerializeField, Min(0.05f)] private float spawnInterval = 0.5f; + [SerializeField, Min(0f)] private float spawnCooldown = 10f; + + [Header("Instant velocity change")] + [SerializeField] private Vector3 localVelocityChange = Vector3.forward * 4.5f; + + [Header("Guaranteed items")] + [SerializeField] private List guaranteedItems = new(); + + [Header("Random items")] + [SerializeField, Min(0)] private int randomItemCount = 5; + [SerializeField] private List randomItems = new(); + + [Header("Spawn position randomization")] + [SerializeField, Min(0f)] private float randomSpawnX = 0.2f; + [SerializeField, Min(0f)] private float randomSpawnZ = 0.2f; + + public float SpawnInterval => spawnInterval; + public float SpawnCooldown => spawnCooldown; + public Vector3 LocalVelocityChange => localVelocityChange; + public IReadOnlyList GuaranteedItems => guaranteedItems; + public int RandomItemCount => randomItemCount; + public IReadOnlyList RandomItems => randomItems; + public float RandomSpawnX => randomSpawnX; + public float RandomSpawnZ => randomSpawnZ; +} diff --git a/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs.meta b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs.meta new file mode 100644 index 0000000..0ffb245 --- /dev/null +++ b/Assets/CONTENT/FEATURES/PipeJunk/Config/ItemPipeConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 142c75ae48de4c7ba6fd0daad6905872 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CONTENT/FEATURES/PipeJunk/ItemPipe.cs b/Assets/CONTENT/FEATURES/PipeJunk/ItemPipe.cs index bd20395..a1d0d28 100644 --- a/Assets/CONTENT/FEATURES/PipeJunk/ItemPipe.cs +++ b/Assets/CONTENT/FEATURES/PipeJunk/ItemPipe.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -6,77 +5,66 @@ using UnityEngine.InputSystem; public class ItemPipe : MonoBehaviour { - [Serializable] - private class GuaranteedItem - { - public GameObject prefab; - - [Min(1)] - public int amount = 1; - } - - [Serializable] - private class RandomItem - { - public GameObject prefab; - - [Min(0)] - public float weight = 1f; - } - [Header("Pipe")] [SerializeField] private Transform spawnPoint; - [SerializeField, Min(0.05f)] private float spawnInterval = 0.5f; - [Header("Instant velocity change")] - [SerializeField] private Vector3 localVelocityChange = Vector3.forward * 4.5f; - - [Header("Guaranteed items")] - [SerializeField] private List guaranteedItems = new(); - - [Header("Random items")] - [SerializeField, Min(0)] private int randomItemCount = 5; - [SerializeField] private List randomItems = new(); - - [Header("Spawn position randomization")] - [SerializeField, Min(0f)] private float randomSpawnX = 0.2f; - [SerializeField, Min(0f)] private float randomSpawnZ = 0.2f; + [Header("Configuration")] + [SerializeField] private ItemPipeConfig config; [Header("Temporary testing")] [SerializeField] private bool spawnOnE = true; private bool isSpawning; + public float CooldownDuration => config != null ? config.SpawnCooldown : 0f; + public float CooldownRemaining { get; private set; } + public int CooldownSecondsRemaining => Mathf.CeilToInt(CooldownRemaining); + public bool CanSpawnItems => config != null && !isSpawning && CooldownRemaining <= 0f; + private void Update() { - if (!spawnOnE || isSpawning || Keyboard.current == null) + if (CooldownRemaining > 0f) + CooldownRemaining = Mathf.Max(0f, CooldownRemaining - Time.deltaTime); + + if (!spawnOnE || Keyboard.current == null) return; if (Keyboard.current.eKey.wasPressedThisFrame) - StartCoroutine(SpawnSequence()); + SpawnItems(); } - private IEnumerator SpawnSequence() + public void SpawnItems() + { + if (!CanSpawnItems) + return; + + StartCoroutine(SpawnSequence(config)); + } + + private IEnumerator SpawnSequence(ItemPipeConfig activeConfig) { isSpawning = true; - List spawnQueue = BuildSpawnQueue(); + List spawnQueue = BuildSpawnQueue(activeConfig); - foreach (GameObject prefab in spawnQueue) + for (int i = 0; i < spawnQueue.Count; i++) { - Spawn(prefab); - yield return new WaitForSeconds(spawnInterval); + Spawn(spawnQueue[i], activeConfig); + + if (i < spawnQueue.Count - 1) + yield return new WaitForSeconds(activeConfig.SpawnInterval); } isSpawning = false; + CooldownRemaining = activeConfig.SpawnCooldown; } - private List BuildSpawnQueue() + private List BuildSpawnQueue(ItemPipeConfig activeConfig) { List queue = new(); // Добавляем предметы в точном количестве. - foreach (GuaranteedItem item in guaranteedItems) + foreach (ItemPipeConfig.GuaranteedItem item in activeConfig.GuaranteedItems) { if (item.prefab == null) continue; @@ -86,9 +74,9 @@ public class ItemPipe : MonoBehaviour } // Выбираем указанное количество случайных предметов. - for (int i = 0; i < randomItemCount; i++) + for (int i = 0; i < activeConfig.RandomItemCount; i++) { - GameObject selectedPrefab = ChooseWeightedRandom(); + GameObject selectedPrefab = ChooseWeightedRandom(activeConfig); if (selectedPrefab != null) queue.Add(selectedPrefab); @@ -100,11 +88,11 @@ public class ItemPipe : MonoBehaviour return queue; } - private GameObject ChooseWeightedRandom() + private GameObject ChooseWeightedRandom(ItemPipeConfig activeConfig) { float totalWeight = 0f; - foreach (RandomItem item in randomItems) + foreach (ItemPipeConfig.RandomItem item in activeConfig.RandomItems) { if (item.prefab != null && item.weight > 0f) totalWeight += item.weight; @@ -113,10 +101,10 @@ public class ItemPipe : MonoBehaviour if (totalWeight <= 0f) return null; - float roll = UnityEngine.Random.value * totalWeight; + float roll = Random.value * totalWeight; float currentWeight = 0f; - foreach (RandomItem item in randomItems) + foreach (ItemPipeConfig.RandomItem item in activeConfig.RandomItems) { if (item.prefab == null || item.weight <= 0f) continue; @@ -134,20 +122,20 @@ public class ItemPipe : MonoBehaviour { for (int i = queue.Count - 1; i > 0; i--) { - int randomIndex = UnityEngine.Random.Range(0, i + 1); + int randomIndex = Random.Range(0, i + 1); (queue[i], queue[randomIndex]) = (queue[randomIndex], queue[i]); } } - private void Spawn(GameObject prefab) + private void Spawn(GameObject prefab, ItemPipeConfig activeConfig) { if (prefab == null || spawnPoint == null) return; - float offsetX = RandomRange(-randomSpawnX, randomSpawnX); - float offsetZ = RandomRange(-randomSpawnZ, randomSpawnZ); + float offsetX = RandomRange(-activeConfig.RandomSpawnX, activeConfig.RandomSpawnX); + float offsetZ = RandomRange(-activeConfig.RandomSpawnZ, activeConfig.RandomSpawnZ); Vector3 spawnPosition = spawnPoint.position + @@ -157,13 +145,13 @@ public class ItemPipe : MonoBehaviour GameObject item = Instantiate( prefab, spawnPosition, - UnityEngine.Random.rotationUniform + Random.rotationUniform ); if (item.TryGetComponent(out Rigidbody body)) { Vector3 worldVelocityChange = - spawnPoint.TransformDirection(localVelocityChange); + spawnPoint.TransformDirection(activeConfig.LocalVelocityChange); body.AddForce(worldVelocityChange, ForceMode.VelocityChange); } @@ -171,6 +159,6 @@ public class ItemPipe : MonoBehaviour private float RandomRange(float min, float max) { - return UnityEngine.Random.Range(min, max); + return Random.Range(min, max); } } diff --git a/Assets/CONTENT/FEATURES/PipeJunk/PrefabsTest/PrefabsTestOr/SpawnJunk.prefab b/Assets/CONTENT/FEATURES/PipeJunk/PrefabsTest/PrefabsTestOr/SpawnJunk.prefab index efb75c5..22b2d84 100644 --- a/Assets/CONTENT/FEATURES/PipeJunk/PrefabsTest/PrefabsTestOr/SpawnJunk.prefab +++ b/Assets/CONTENT/FEATURES/PipeJunk/PrefabsTest/PrefabsTestOr/SpawnJunk.prefab @@ -42,22 +42,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d2976eecf10dffe429030900016fa86d, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: spawnPoint: {fileID: 286431562970531899} - spawnInterval: 0.05 - localVelocityChange: {x: 0, y: -5, z: 0} - guaranteedItems: - - prefab: {fileID: 4504260422113134419, guid: 8790cd6f776403940ac664c5db12dab4, type: 3} - amount: 1 - randomItemCount: 7 - randomItems: - - prefab: {fileID: 2474374521670934351, guid: c91d2337125ccaf45a0c57af9a6703c8, type: 3} - weight: 1 - - prefab: {fileID: 4728426142119307488, guid: 795e138cd804c7c42aa508895e6a61df, type: 3} - weight: 1 - - prefab: {fileID: 4504260422113134419, guid: 8790cd6f776403940ac664c5db12dab4, type: 3} - weight: 3 - randomSpawnX: 1 - randomSpawnZ: 1 + config: {fileID: 11400000, guid: 3883e23238f84f748e616770b66fa885, type: 2} spawnOnE: 1 diff --git a/ProjectSettings/Packages/com.unity.probuilder/Settings.json b/ProjectSettings/Packages/com.unity.probuilder/Settings.json index bfb4593..f9d003f 100644 --- a/ProjectSettings/Packages/com.unity.probuilder/Settings.json +++ b/ProjectSettings/Packages/com.unity.probuilder/Settings.json @@ -104,7 +104,7 @@ { "type": "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "key": "ShapeBuilder.ActiveShapeIndex", - "value": "{\"m_Value\":7}" + "value": "{\"m_Value\":6}" }, { "type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", @@ -119,7 +119,7 @@ { "type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "key": "ShapeBuilder.LastSize.Cylinder", - "value": "{\"m_Value\":{\"x\":4.177962303161621,\"y\":0.2011122703552246,\"z\":-4.202449798583984}}" + "value": "{\"m_Value\":{\"x\":-0.4658929109573364,\"y\":0.78654944896698,\"z\":-0.47608280181884768}}" }, { "type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",