Untitled
csharp
a month ago
12 kB
2
Indexable
Never
using Sirenix.OdinInspector; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class ClosetGenerator : SerializedMonoBehaviour { [Title("tube properties")] public float radius = 10; public int boxesPerLevel = 36; public int numberOfLevels = 20; public float boxHeight = 2f; public Material tubeMaterial; public ParticleSystem _poofParticle; [Title("drawer properties")] public float drawerDepth = 1f; public float drawerBackThickness = 0.3f; public float drawerSidesThickness = 0.3f; public float drawerUpDownThickness = 0.3f; public float colliderSideScale = 1.3f; [Title("drawer spacing")] public float drawerSideSpacing = 0.1f; public float drawerVerticalSpacing = 0.1f; [Title("assets")] public float spawnProbability = 0.6f; public float assetsScale = 1f; public float assetsSpacing = 1f; public List<AssetsParams> _assetsToSpawn; public List<GameObject> _spawnedAssets; public struct AssetsParams { public GameObject asset; public Vector3 rotation; public float offset; } [Title("fall animation")] [SerializeField] public float animTime = 1f; public AnimationCurve _animCurve; public float blinktime = 1; public float destroyTime = 1; [Title("objects list")] public List<List<ClosetCell>> drawerList = new List<List<ClosetCell>>(); private void Update() { } [Button] private void GenerateTube() { ClearTube(); GameObject tubeParent = new GameObject(); tubeParent.transform.parent = this.transform; float anglePerBox = 360f / boxesPerLevel; //generating tube for (int y = 0; y < numberOfLevels; y++) { float height = (boxHeight * (y + 1)) - (boxHeight * 0.5f); List<ClosetCell> horizontalDrawers = new List<ClosetCell>(); for (int x = 0; x < boxesPerLevel; x++) { GameObject myBox = new GameObject(); myBox.transform.position = new Vector3(0f, height, 0f); myBox.transform.parent = tubeParent.transform; myBox.transform.eulerAngles = new Vector3(0, anglePerBox * x, 0); myBox.transform.Translate(Vector3.forward * radius); myBox.transform.localScale = new Vector3(1, 1 - (drawerVerticalSpacing / 2), 1); DestroyImmediate(myBox.GetComponent<MeshRenderer>()); myBox.layer = LayerMask.NameToLayer("Tube"); myBox.name = x.ToString() + "," + y.ToString(); var closetCell = myBox.AddComponent<ClosetCell>(); closetCell.index = new Vector2Int(x, y); horizontalDrawers.Add(closetCell); GenerateChildDrawer(myBox); } drawerList.Add(horizontalDrawers); } //spawning assets in tube } [Button] private void spawnAssets() { for (int y = 0; y < numberOfLevels; y++) { for (int x = 0; x < boxesPerLevel; x++) { for (int i = 0; i < 3; i++) { if (Random.Range(0f, 1f)<spawnProbability) { int random = Random.Range(0, _assetsToSpawn.Count); var go = _assetsToSpawn[random].asset; var rotation = _assetsToSpawn[random].rotation; var offset = _assetsToSpawn[random].offset; Vector3 position = new Vector3((i - 1) * assetsSpacing, 0, -drawerDepth / 2); drawerList[y][x].AddObject(go, position, rotation, assetsScale, offset, boxHeight * 0.85f, i, colliderSideScale); } else { Vector3 position = new Vector3((i - 1) * assetsSpacing, 0, -drawerDepth / 2); drawerList[y][x].AddObject(null, position, Vector3.zero, 1, 0, boxHeight * 0.85f, i, colliderSideScale); } } } } } [Button] public void DestroyCell(Vector2Int cell) { List<GameObject> objectsToAnimate = new List<GameObject>(); List<float> startPositions = new List<float>(); List<float> endpositions = new List<float>(); for (int y = 0; y < numberOfLevels; y++) { for (int x = 0; x < boxesPerLevel; x++) { if (x == cell.x && y > cell.y) { if (drawerList[y][x] != null) { objectsToAnimate.Add(drawerList[y][x].gameObject); Debug.Log(drawerList[y][x].gameObject.name); startPositions.Add(drawerList[y][x].transform.position.y); endpositions.Add(drawerList[y][x].transform.position.y - boxHeight); } } } } Destroy(drawerList[cell.y][cell.x].gameObject); drawerList[cell.y][cell.x] = null; StartCoroutine(Animate(objectsToAnimate.ToArray(), startPositions.ToArray(), endpositions.ToArray())); } public void CheckCell(Vector2Int cell) { if(drawerList[cell.y][cell.x]._slots[0].item.name == drawerList[cell.y][cell.x]._slots[1].item.name && drawerList[cell.y][cell.x]._slots[2].item.name == drawerList[cell.y][cell.x]._slots[1].item.name) { StartCoroutine(DestroyCoroutine(cell)); } } private IEnumerator DestroyCoroutine(Vector2Int cell) { drawerList[cell.y][cell.x]._slots[0].item.GetComponent<Item>().Blink(blinktime); drawerList[cell.y][cell.x]._slots[1].item.GetComponent<Item>().Blink(blinktime); drawerList[cell.y][cell.x]._slots[2].item.GetComponent<Item>().Blink(blinktime); yield return new WaitForSeconds(destroyTime); _poofParticle.transform.position = drawerList[cell.y][cell.x].transform.position; _poofParticle.transform.eulerAngles = drawerList[cell.y][cell.x].transform.eulerAngles; _poofParticle.Play(); DestroyCell(cell); } private IEnumerator Animate(GameObject[] objectsToAnimate, float[] startPositions, float[] endpositions) { if (objectsToAnimate == null || objectsToAnimate.Length == 0) { Debug.LogWarning("No objects to animate."); yield break; } float elapsedTime = 0f; while (elapsedTime < animTime) { Debug.Log("animating"); float t = elapsedTime / animTime; float curveValue = _animCurve.Evaluate(t); for (int i = 0; i < objectsToAnimate.Length; i++) { Vector3 newPosition = Vector3.Lerp( new Vector3(objectsToAnimate[i].transform.position.x, startPositions[i], objectsToAnimate[i].transform.position.z), new Vector3(objectsToAnimate[i].transform.position.x, endpositions[i], objectsToAnimate[i].transform.position.z), 1 - curveValue); objectsToAnimate[i].transform.position = newPosition; } elapsedTime += Time.deltaTime; yield return null; } for (int i = 0; i < objectsToAnimate.Length; i++) { objectsToAnimate[i].transform.position = new Vector3(objectsToAnimate[i].transform.position.x, endpositions[i], objectsToAnimate[i].transform.position.z); } } private void GenerateChildDrawer(GameObject cell) { GameObject drawerBack = GameObject.CreatePrimitive(PrimitiveType.Cube); drawerBack.name = "drawerBack"; drawerBack.transform.parent = cell.transform; drawerBack.transform.localPosition = Vector3.zero - new Vector3(0, 0, drawerDepth); drawerBack.transform.localEulerAngles = Vector3.zero; drawerBack.transform.localScale = new Vector3(((2 * Mathf.PI * (radius - drawerDepth)) / boxesPerLevel), boxHeight, drawerBackThickness); drawerBack.layer = LayerMask.NameToLayer("Tube"); if (tubeMaterial != null) drawerBack.GetComponent<Renderer>().material = tubeMaterial; float sidePosition = (((2 * Mathf.PI * (radius - (drawerDepth * 0.5f))) / boxesPerLevel) / 2) * 1 - drawerSideSpacing; GameObject drawerLeft = GameObject.CreatePrimitive(PrimitiveType.Cube); drawerLeft.name = "drawerLeft"; drawerLeft.transform.parent = cell.transform; drawerLeft.transform.localPosition = new Vector3(sidePosition, 0, -drawerDepth / 2); drawerLeft.transform.LookAt(new Vector3(0, drawerLeft.transform.position.y, 0)); drawerLeft.transform.localScale = new Vector3(drawerSidesThickness, boxHeight, drawerDepth); drawerLeft.layer = LayerMask.NameToLayer("Tube"); if (tubeMaterial != null) drawerLeft.GetComponent<Renderer>().material = tubeMaterial; GameObject drawerRight = GameObject.CreatePrimitive(PrimitiveType.Cube); drawerRight.name = "drawerRight"; drawerRight.transform.parent = cell.transform; drawerRight.transform.localPosition = new Vector3(-sidePosition, 0, -drawerDepth / 2); drawerRight.transform.LookAt(new Vector3(0, drawerRight.transform.position.y, 0)); drawerRight.transform.localScale = new Vector3(drawerSidesThickness, boxHeight, drawerDepth); drawerRight.layer = LayerMask.NameToLayer("Tube"); if (tubeMaterial != null) drawerRight.GetComponent<Renderer>().material = tubeMaterial; int subparts = 5; for (int i = 0; i < subparts; i++) { GameObject drawerUp = GameObject.CreatePrimitive(PrimitiveType.Cube); drawerUp.name = "drawerUp"; drawerUp.transform.parent = cell.transform; drawerUp.transform.localPosition = new Vector3(0, (boxHeight / 2) - (drawerUpDownThickness / 2), (-drawerDepth * (i + 0.5f)) / subparts); drawerUp.transform.LookAt(new Vector3(0, drawerUp.transform.position.y, 0)); float myRadius = (2 * Mathf.PI * (Vector3.Distance(drawerUp.transform.position, new Vector3(0, drawerUp.transform.position.y, 0))) / boxesPerLevel); drawerUp.transform.localScale = new Vector3(myRadius - drawerSidesThickness, drawerUpDownThickness, drawerDepth / subparts); if (tubeMaterial != null) drawerUp.GetComponent<Renderer>().material = tubeMaterial; drawerUp.layer = LayerMask.NameToLayer("Tube"); GameObject drawerDown = Instantiate(drawerUp, drawerUp.transform.parent, false); drawerDown.name = "drawerDown"; //drawerDown.transform.parent = drawerUp.transform.parent; drawerDown.transform.localPosition = new Vector3(drawerDown.transform.localPosition.x, -drawerDown.transform.localPosition.y, drawerDown.transform.localPosition.z); } } [Button] private void ClearTube() { drawerList.Clear(); _spawnedAssets.Clear(); Transform[] meshRenderers = this.transform.GetComponentsInChildren<Transform>(); for (int i = 0; i < meshRenderers.Length; i++) { if (meshRenderers[i] != this.transform) { DestroyImmediate(meshRenderers[i].gameObject); } } } }