101 lines
3.5 KiB
C#
101 lines
3.5 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
public class BlockDrop_BlockManager3D : MonoBehaviour
|
|
{
|
|
[Header("Parent for blocks")]
|
|
public Transform blockParent; // drag your parent Transform here
|
|
|
|
[Header("Grid (local values relative to parent)")]
|
|
public Vector3 localGridOrigin = new Vector3(0f, 6f, 0f);
|
|
public int columns = 16;
|
|
public float cellSize = 1f;
|
|
public float spawnHeight = 12f;
|
|
|
|
[Header("Prefabs")]
|
|
public GameObject normalBlock;
|
|
public GameObject indestructibleBlock;
|
|
public GameObject berryBlock;
|
|
|
|
[Header("Rates")]
|
|
public float fallInterval = 1.2f;
|
|
[Range(0f, 1f)] public float indestructibleChance = 0.15f;
|
|
[Range(0f, 1f)] public float berryChance = 0.12f;
|
|
|
|
[Header("Existing Blocks")]
|
|
public bool convertExistingChildren = true;
|
|
public float existingBlockFallDelay = 2f; // delay before existing blocks start falling
|
|
|
|
private List<BlockDrop_Block> staticBlocks = new List<BlockDrop_Block>();
|
|
private List<BlockDrop_Block> fallingBlocks = new List<BlockDrop_Block>();
|
|
|
|
void Start()
|
|
{
|
|
if (convertExistingChildren && blockParent != null)
|
|
{
|
|
foreach (Transform child in blockParent)
|
|
{
|
|
// ensure each child has a Block component
|
|
BlockDrop_Block block = child.GetComponent<BlockDrop_Block>();
|
|
if (block == null) block = child.gameObject.AddComponent<BlockDrop_Block>();
|
|
|
|
// check if it should be static (indestructible walls) or falling
|
|
if (block.type == BlockDrop_BlockType.Indestructible)
|
|
{
|
|
staticBlocks.Add(block);
|
|
}
|
|
else
|
|
{
|
|
fallingBlocks.Add(block);
|
|
// disable rigidbody so it doesn't fall immediately
|
|
Rigidbody rb = child.GetComponent<Rigidbody>();
|
|
if (rb == null) rb = child.gameObject.AddComponent<Rigidbody>();
|
|
rb.isKinematic = true;
|
|
}
|
|
}
|
|
|
|
// schedule falling for existing blocks
|
|
InvokeRepeating(nameof(DropExistingBlock), existingBlockFallDelay, fallInterval);
|
|
}
|
|
|
|
// schedule normal falling spawns
|
|
InvokeRepeating(nameof(SpawnFallingBlock), 1.5f, fallInterval);
|
|
}
|
|
|
|
void DropExistingBlock()
|
|
{
|
|
if (fallingBlocks.Count == 0) return;
|
|
|
|
// pick one existing block and enable falling
|
|
BlockDrop_Block block = fallingBlocks[0];
|
|
fallingBlocks.RemoveAt(0);
|
|
|
|
Rigidbody rb = block.GetComponent<Rigidbody>();
|
|
if (rb != null) rb.isKinematic = false; // let it fall with gravity
|
|
}
|
|
|
|
public void SpawnFallingBlock()
|
|
{
|
|
int col = Random.Range(0, columns);
|
|
|
|
// Local position relative to parent
|
|
Vector3 localSpawnPos = new Vector3(localGridOrigin.x + col * cellSize, spawnHeight, localGridOrigin.z);
|
|
|
|
// Convert to world position
|
|
Vector3 worldSpawnPos = blockParent != null
|
|
? blockParent.TransformPoint(localSpawnPos)
|
|
: localSpawnPos;
|
|
|
|
// Choose prefab
|
|
float r = Random.value;
|
|
GameObject prefab = normalBlock;
|
|
if (r < indestructibleChance) prefab = indestructibleBlock;
|
|
else if (r < indestructibleChance + berryChance) prefab = berryBlock;
|
|
|
|
// Instantiate under parent
|
|
GameObject blockObj = Instantiate(prefab, worldSpawnPos, Quaternion.identity, blockParent);
|
|
Rigidbody rbObj= blockObj.GetComponent<Rigidbody>();
|
|
rbObj.isKinematic = false;
|
|
}
|
|
}
|