Squashed commit of the following:
commit7912604fafAuthor: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 11 17:22:28 2026 +0300 update .gitignore commitd71b90c8bdAuthor: henjkey <henjkey@gmail.com> Date: Tue Aug 11 18:42:09 2026 +0500 Edited Добавлен таймер, конфиг и публичный метод SpawnItems() CooldownRemaining - оставшееся время до спавна float CooldownSecondsRemaining - оставшееся время до спавна int commit5b888fba95Author: AsanoRema <asanorema2036@gmail.com> Date: Tue Aug 11 10:30:09 2026 +0300 Changed .gitignore commite3d5561fc8Author: henjkey <henjkey@gmail.com> Date: Tue Aug 11 10:47:35 2026 +0500 New Второй спавнер с нормальными настройками и обновленные префабы
This commit is contained in:
@@ -77,3 +77,5 @@ crashlytics-build.properties
|
|||||||
/[Aa]ssets/[Ss]treamingAssets/aa/*
|
/[Aa]ssets/[Ss]treamingAssets/aa/*
|
||||||
|
|
||||||
ProjectSettings/Packages/com.unity.probuilder/Settings.json
|
ProjectSettings/Packages/com.unity.probuilder/Settings.json
|
||||||
|
Assets/Editor/x64/Bakery/.uvgblog.txt
|
||||||
|
Assets/Editor/x64/Bakery/.uvgblog.txt
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bb903df62880440f80782f53ec0f6692
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3883e23238f84f748e616770b66fa885
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -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<GuaranteedItem> guaranteedItems = new();
|
||||||
|
|
||||||
|
[Header("Random items")]
|
||||||
|
[SerializeField, Min(0)] private int randomItemCount = 5;
|
||||||
|
[SerializeField] private List<RandomItem> 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<GuaranteedItem> GuaranteedItems => guaranteedItems;
|
||||||
|
public int RandomItemCount => randomItemCount;
|
||||||
|
public IReadOnlyList<RandomItem> RandomItems => randomItems;
|
||||||
|
public float RandomSpawnX => randomSpawnX;
|
||||||
|
public float RandomSpawnZ => randomSpawnZ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 142c75ae48de4c7ba6fd0daad6905872
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -6,77 +5,66 @@ using UnityEngine.InputSystem;
|
|||||||
|
|
||||||
public class ItemPipe : MonoBehaviour
|
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")]
|
[Header("Pipe")]
|
||||||
[SerializeField] private Transform spawnPoint;
|
[SerializeField] private Transform spawnPoint;
|
||||||
[SerializeField, Min(0.05f)] private float spawnInterval = 0.5f;
|
|
||||||
|
|
||||||
[Header("Instant velocity change")]
|
[Header("Configuration")]
|
||||||
[SerializeField] private Vector3 localVelocityChange = Vector3.forward * 4.5f;
|
[SerializeField] private ItemPipeConfig config;
|
||||||
|
|
||||||
[Header("Guaranteed items")]
|
|
||||||
[SerializeField] private List<GuaranteedItem> guaranteedItems = new();
|
|
||||||
|
|
||||||
[Header("Random items")]
|
|
||||||
[SerializeField, Min(0)] private int randomItemCount = 5;
|
|
||||||
[SerializeField] private List<RandomItem> randomItems = new();
|
|
||||||
|
|
||||||
[Header("Spawn position randomization")]
|
|
||||||
[SerializeField, Min(0f)] private float randomSpawnX = 0.2f;
|
|
||||||
[SerializeField, Min(0f)] private float randomSpawnZ = 0.2f;
|
|
||||||
|
|
||||||
[Header("Temporary testing")]
|
[Header("Temporary testing")]
|
||||||
[SerializeField] private bool spawnOnE = true;
|
[SerializeField] private bool spawnOnE = true;
|
||||||
|
|
||||||
private bool isSpawning;
|
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()
|
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;
|
return;
|
||||||
|
|
||||||
if (Keyboard.current.eKey.wasPressedThisFrame)
|
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;
|
isSpawning = true;
|
||||||
|
|
||||||
List<GameObject> spawnQueue = BuildSpawnQueue();
|
List<GameObject> spawnQueue = BuildSpawnQueue(activeConfig);
|
||||||
|
|
||||||
foreach (GameObject prefab in spawnQueue)
|
for (int i = 0; i < spawnQueue.Count; i++)
|
||||||
{
|
{
|
||||||
Spawn(prefab);
|
Spawn(spawnQueue[i], activeConfig);
|
||||||
yield return new WaitForSeconds(spawnInterval);
|
|
||||||
|
if (i < spawnQueue.Count - 1)
|
||||||
|
yield return new WaitForSeconds(activeConfig.SpawnInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
isSpawning = false;
|
isSpawning = false;
|
||||||
|
CooldownRemaining = activeConfig.SpawnCooldown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<GameObject> BuildSpawnQueue()
|
private List<GameObject> BuildSpawnQueue(ItemPipeConfig activeConfig)
|
||||||
{
|
{
|
||||||
List<GameObject> queue = new();
|
List<GameObject> queue = new();
|
||||||
|
|
||||||
// Добавляем предметы в точном количестве.
|
// Добавляем предметы в точном количестве.
|
||||||
foreach (GuaranteedItem item in guaranteedItems)
|
foreach (ItemPipeConfig.GuaranteedItem item in activeConfig.GuaranteedItems)
|
||||||
{
|
{
|
||||||
if (item.prefab == null)
|
if (item.prefab == null)
|
||||||
continue;
|
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)
|
if (selectedPrefab != null)
|
||||||
queue.Add(selectedPrefab);
|
queue.Add(selectedPrefab);
|
||||||
@@ -100,11 +88,11 @@ public class ItemPipe : MonoBehaviour
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GameObject ChooseWeightedRandom()
|
private GameObject ChooseWeightedRandom(ItemPipeConfig activeConfig)
|
||||||
{
|
{
|
||||||
float totalWeight = 0f;
|
float totalWeight = 0f;
|
||||||
|
|
||||||
foreach (RandomItem item in randomItems)
|
foreach (ItemPipeConfig.RandomItem item in activeConfig.RandomItems)
|
||||||
{
|
{
|
||||||
if (item.prefab != null && item.weight > 0f)
|
if (item.prefab != null && item.weight > 0f)
|
||||||
totalWeight += item.weight;
|
totalWeight += item.weight;
|
||||||
@@ -113,10 +101,10 @@ public class ItemPipe : MonoBehaviour
|
|||||||
if (totalWeight <= 0f)
|
if (totalWeight <= 0f)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
float roll = UnityEngine.Random.value * totalWeight;
|
float roll = Random.value * totalWeight;
|
||||||
float currentWeight = 0f;
|
float currentWeight = 0f;
|
||||||
|
|
||||||
foreach (RandomItem item in randomItems)
|
foreach (ItemPipeConfig.RandomItem item in activeConfig.RandomItems)
|
||||||
{
|
{
|
||||||
if (item.prefab == null || item.weight <= 0f)
|
if (item.prefab == null || item.weight <= 0f)
|
||||||
continue;
|
continue;
|
||||||
@@ -134,20 +122,20 @@ public class ItemPipe : MonoBehaviour
|
|||||||
{
|
{
|
||||||
for (int i = queue.Count - 1; i > 0; i--)
|
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[i], queue[randomIndex]) =
|
||||||
(queue[randomIndex], queue[i]);
|
(queue[randomIndex], queue[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Spawn(GameObject prefab)
|
private void Spawn(GameObject prefab, ItemPipeConfig activeConfig)
|
||||||
{
|
{
|
||||||
if (prefab == null || spawnPoint == null)
|
if (prefab == null || spawnPoint == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float offsetX = RandomRange(-randomSpawnX, randomSpawnX);
|
float offsetX = RandomRange(-activeConfig.RandomSpawnX, activeConfig.RandomSpawnX);
|
||||||
float offsetZ = RandomRange(-randomSpawnZ, randomSpawnZ);
|
float offsetZ = RandomRange(-activeConfig.RandomSpawnZ, activeConfig.RandomSpawnZ);
|
||||||
|
|
||||||
Vector3 spawnPosition =
|
Vector3 spawnPosition =
|
||||||
spawnPoint.position +
|
spawnPoint.position +
|
||||||
@@ -157,13 +145,13 @@ public class ItemPipe : MonoBehaviour
|
|||||||
GameObject item = Instantiate(
|
GameObject item = Instantiate(
|
||||||
prefab,
|
prefab,
|
||||||
spawnPosition,
|
spawnPosition,
|
||||||
UnityEngine.Random.rotationUniform
|
Random.rotationUniform
|
||||||
);
|
);
|
||||||
|
|
||||||
if (item.TryGetComponent(out Rigidbody body))
|
if (item.TryGetComponent(out Rigidbody body))
|
||||||
{
|
{
|
||||||
Vector3 worldVelocityChange =
|
Vector3 worldVelocityChange =
|
||||||
spawnPoint.TransformDirection(localVelocityChange);
|
spawnPoint.TransformDirection(activeConfig.LocalVelocityChange);
|
||||||
|
|
||||||
body.AddForce(worldVelocityChange, ForceMode.VelocityChange);
|
body.AddForce(worldVelocityChange, ForceMode.VelocityChange);
|
||||||
}
|
}
|
||||||
@@ -171,6 +159,6 @@ public class ItemPipe : MonoBehaviour
|
|||||||
|
|
||||||
private float RandomRange(float min, float max)
|
private float RandomRange(float min, float max)
|
||||||
{
|
{
|
||||||
return UnityEngine.Random.Range(min, max);
|
return Random.Range(min, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+223
-224
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,11 @@ MonoBehaviour:
|
|||||||
SourcePrefabToOverride: {fileID: 0}
|
SourcePrefabToOverride: {fileID: 0}
|
||||||
SourceHashToOverride: 0
|
SourceHashToOverride: 0
|
||||||
OverridingTargetPrefab: {fileID: 0}
|
OverridingTargetPrefab: {fileID: 0}
|
||||||
|
- Override: 0
|
||||||
|
Prefab: {fileID: 8335220146391086898, guid: 3bfc25c2194679746bdc7441f889af7c, type: 3}
|
||||||
|
SourcePrefabToOverride: {fileID: 0}
|
||||||
|
SourceHashToOverride: 0
|
||||||
|
OverridingTargetPrefab: {fileID: 0}
|
||||||
- Override: 0
|
- Override: 0
|
||||||
Prefab: {fileID: 2182525189444712253, guid: 7f5a91b903d654342bfb77c0b9126aa3, type: 3}
|
Prefab: {fileID: 2182525189444712253, guid: 7f5a91b903d654342bfb77c0b9126aa3, type: 3}
|
||||||
SourcePrefabToOverride: {fileID: 0}
|
SourcePrefabToOverride: {fileID: 0}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user