TG9six 03a642d635 first push
first push
2025-09-06 17:17:39 +04:00

108 lines
4.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace GPUInstancer
{
public class AstroidGenerator : MonoBehaviour
{
[Range(0, 200000)]
public int count = 50000;
public List<GPUInstancerPrefab> asteroidObjects = new List<GPUInstancerPrefab>();
public GPUInstancerPrefabManager prefabManager;
public Transform centerTransform;
private List<GPUInstancerPrefab> asteroidInstances = new List<GPUInstancerPrefab>();
private int instantiatedCount;
private Vector3 center;
private Vector3 allocatedPos;
private Quaternion allocatedRot;
private Vector3 allocatedLocalEulerRot;
private Vector3 allocatedLocalScale;
private GPUInstancerPrefab allocatedGO;
private GameObject goParent;
private float allocatedLocalScaleFactor;
private int columnSize;
private int columnSpace = 3;
private void Awake()
{
instantiatedCount = 0;
center = centerTransform.position;
allocatedPos = Vector3.zero;
allocatedRot = Quaternion.identity;
allocatedLocalEulerRot = Vector3.zero;
allocatedLocalScale = Vector3.one;
allocatedLocalScaleFactor = 1f;
goParent = new GameObject("Asteroids");
goParent.transform.position = center;
goParent.transform.parent = gameObject.transform;
columnSize = count < 5000 ? 1 : count / 2500;
int firstPassColumnSize = count % columnSize > 0 ? columnSize - 1 : columnSize;
asteroidInstances.Clear();
for (int h = 0; h < firstPassColumnSize; h++)
{
for (int i = 0; i < Mathf.FloorToInt((float)count / columnSize); i++)
{
asteroidInstances.Add(InstantiateInCircle(center, h));
}
}
if (firstPassColumnSize != columnSize)
{
for (int i = 0; i < count - (Mathf.FloorToInt((float)count / columnSize) * firstPassColumnSize); i++)
{
asteroidInstances.Add(InstantiateInCircle(center, columnSize));
}
}
Debug.Log("Instantiated " + instantiatedCount + " objects.");
}
private void Start()
{
if (prefabManager != null && prefabManager.gameObject.activeSelf && prefabManager.enabled)
{
GPUInstancerAPI.RegisterPrefabInstanceList(prefabManager, asteroidInstances);
GPUInstancerAPI.InitializeGPUInstancer(prefabManager);
}
}
private void SetRandomPosInCircle(Vector3 center, int column, float radius)
{
float ang = Random.value * 360;
allocatedPos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
allocatedPos.y = center.y - (column * (float)columnSpace / 2) + (column * columnSpace) + Random.Range(0f, 1f);
allocatedPos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
}
private GPUInstancerPrefab InstantiateInCircle(Vector3 center, int column)
{
SetRandomPosInCircle(center, column - Mathf.FloorToInt(columnSize / 2f), Random.Range(80.0f, 150f));
allocatedRot = Quaternion.FromToRotation(Vector3.forward, center - allocatedPos);
allocatedGO = Instantiate(asteroidObjects[Random.Range(0, asteroidObjects.Count)], allocatedPos, allocatedRot);
allocatedGO.transform.parent = goParent.transform;
allocatedLocalEulerRot.x = Random.Range(-180f, 180f);
allocatedLocalEulerRot.y = Random.Range(-180f, 180f);
allocatedLocalEulerRot.z = Random.Range(-180f, 180f);
allocatedGO.transform.localRotation = Quaternion.Euler(allocatedLocalEulerRot);
allocatedLocalScaleFactor = Random.Range(0.3f, 1.2f);
allocatedLocalScale.x = allocatedLocalScaleFactor;
allocatedLocalScale.y = allocatedLocalScaleFactor;
allocatedLocalScale.z = allocatedLocalScaleFactor;
allocatedGO.transform.localScale = allocatedLocalScale;
instantiatedCount++;
return allocatedGO;
}
}
}