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 Второй спавнер с нормальными настройками и обновленные префабы
177 lines
4.6 KiB
C#
177 lines
4.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
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<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")]
|
|
[SerializeField] private bool spawnOnE = true;
|
|
|
|
private bool isSpawning;
|
|
|
|
private void Update()
|
|
{
|
|
if (!spawnOnE || isSpawning || Keyboard.current == null)
|
|
return;
|
|
|
|
if (Keyboard.current.eKey.wasPressedThisFrame)
|
|
StartCoroutine(SpawnSequence());
|
|
}
|
|
|
|
private IEnumerator SpawnSequence()
|
|
{
|
|
isSpawning = true;
|
|
|
|
List<GameObject> spawnQueue = BuildSpawnQueue();
|
|
|
|
foreach (GameObject prefab in spawnQueue)
|
|
{
|
|
Spawn(prefab);
|
|
yield return new WaitForSeconds(spawnInterval);
|
|
}
|
|
|
|
isSpawning = false;
|
|
}
|
|
|
|
private List<GameObject> BuildSpawnQueue()
|
|
{
|
|
List<GameObject> queue = new();
|
|
|
|
// Добавляем предметы в точном количестве.
|
|
foreach (GuaranteedItem item in guaranteedItems)
|
|
{
|
|
if (item.prefab == null)
|
|
continue;
|
|
|
|
for (int i = 0; i < item.amount; i++)
|
|
queue.Add(item.prefab);
|
|
}
|
|
|
|
// Выбираем указанное количество случайных предметов.
|
|
for (int i = 0; i < randomItemCount; i++)
|
|
{
|
|
GameObject selectedPrefab = ChooseWeightedRandom();
|
|
|
|
if (selectedPrefab != null)
|
|
queue.Add(selectedPrefab);
|
|
}
|
|
|
|
// Перемешиваем гарантированные и случайные предметы вместе.
|
|
Shuffle(queue);
|
|
|
|
return queue;
|
|
}
|
|
|
|
private GameObject ChooseWeightedRandom()
|
|
{
|
|
float totalWeight = 0f;
|
|
|
|
foreach (RandomItem item in randomItems)
|
|
{
|
|
if (item.prefab != null && item.weight > 0f)
|
|
totalWeight += item.weight;
|
|
}
|
|
|
|
if (totalWeight <= 0f)
|
|
return null;
|
|
|
|
float roll = UnityEngine.Random.value * totalWeight;
|
|
float currentWeight = 0f;
|
|
|
|
foreach (RandomItem item in randomItems)
|
|
{
|
|
if (item.prefab == null || item.weight <= 0f)
|
|
continue;
|
|
|
|
currentWeight += item.weight;
|
|
|
|
if (roll < currentWeight)
|
|
return item.prefab;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void Shuffle(List<GameObject> queue)
|
|
{
|
|
for (int i = queue.Count - 1; i > 0; i--)
|
|
{
|
|
int randomIndex = UnityEngine.Random.Range(0, i + 1);
|
|
|
|
(queue[i], queue[randomIndex]) =
|
|
(queue[randomIndex], queue[i]);
|
|
}
|
|
}
|
|
|
|
private void Spawn(GameObject prefab)
|
|
{
|
|
if (prefab == null || spawnPoint == null)
|
|
return;
|
|
|
|
float offsetX = RandomRange(-randomSpawnX, randomSpawnX);
|
|
float offsetZ = RandomRange(-randomSpawnZ, randomSpawnZ);
|
|
|
|
Vector3 spawnPosition =
|
|
spawnPoint.position +
|
|
spawnPoint.right * offsetX +
|
|
spawnPoint.forward * offsetZ;
|
|
|
|
GameObject item = Instantiate(
|
|
prefab,
|
|
spawnPosition,
|
|
UnityEngine.Random.rotationUniform
|
|
);
|
|
|
|
if (item.TryGetComponent(out Rigidbody body))
|
|
{
|
|
Vector3 worldVelocityChange =
|
|
spawnPoint.TransformDirection(localVelocityChange);
|
|
|
|
body.AddForce(worldVelocityChange, ForceMode.VelocityChange);
|
|
}
|
|
}
|
|
|
|
private float RandomRange(float min, float max)
|
|
{
|
|
return UnityEngine.Random.Range(min, max);
|
|
}
|
|
}
|