using System; using Ext.B83.Unity.Attributes; using UnityEngine; using Random = UnityEngine.Random; namespace InterfaceOff { [Serializable] public struct SpawnableWindowType { [field: SerializeField, MonoScript] private string Typename { get; set; } public Type Type => Type.GetType(Typename); [field: SerializeField] public int SpawnWeight { get; private set; } } public class WindowSpawner : MonoBehaviour { [field: SerializeField] private GameObject SampleChild { get; set; } [field: SerializeField] private Canvas GameCanvas { get; set; } [field: SerializeField] private SpawnableWindowType[] WindowTypes { get; set; } private int TotalSpawnWeight { get; set; } [field: SerializeField] public bool AutoSpawn { get; private set; } = true; private int SpawnCounter { get; set; } private void Awake() { /* Logs the amount of types found and errors if there is none */ Debug.Log($"Found [{WindowTypes.Length}] different window types "); if (WindowTypes.Length == 0) { Debug.LogError("Could not find any window types"); return; } /* Calculates the total spawn weight */ TotalSpawnWeight = 0; foreach (SpawnableWindowType type in WindowTypes) { TotalSpawnWeight += type.SpawnWeight; } } private Type GetRandomWindowType() { int currentTypeWeight = Random.Range(0, TotalSpawnWeight); foreach (SpawnableWindowType type in WindowTypes) { currentTypeWeight -= type.SpawnWeight; if (currentTypeWeight <= 0) { return type.Type; } } return WindowTypes[0].Type; } private void SpawnNewRandomWindow() { /* Creates the gameobject with a random class */ GameObject go = Instantiate(SampleChild, GameCanvas.transform); go.SetActive(true); Type type = GetRandomWindowType(); go.name = type.Name; WindowBase windowBase = go.AddComponent(type) as WindowBase; /* Checks it created correctly before instantiating further */ if (DebugUtils.IsNull(windowBase)) { Debug.LogError("How did this happen"); return; } /* Makes sure the WindowInteractions and WindowComponents are setup before passing to user code */ windowBase.Interactions = go.GetComponent(); windowBase.Interactions.SetAttachedTo(windowBase); windowBase.Components = go.GetComponent(); windowBase.InstantiateWindowBase(); } private void FixedUpdate() { if (AutoSpawn) { const int TICKS_PER_SECOND = 20; const int MINIMUM_SPAWN_TIME = 2 * 20; const int MAXIMUM_SPAWN_TIME = 5 * 20; /* Decreases the spawn counter and spawns if at 0 */ SpawnCounter = Math.Max(0, SpawnCounter - 1); if (SpawnCounter == 0) { SpawnCounter = Random.Range(MINIMUM_SPAWN_TIME, MAXIMUM_SPAWN_TIME); SpawnNewRandomWindow(); } } } private void Update() { if (!AutoSpawn) { if (Input.GetKeyDown(KeyCode.Space)) { SpawnNewRandomWindow(); } } } } }