using UnityEngine; using UnityEngine.InputSystem; public class BuildingManager : MonoBehaviour, IListener { [SerializeField] private BuilderPCUIBehaviour ui = null; [SerializeField] private float buildingMoveSpeed = 3f; [Tooltip("Opóźnienie przed włączeniem możliwości ustawienia kolejnego budynku.")] [SerializeField] private float buildDelay = 1f; [SerializeField] private float leftSpawnX = -10f; [SerializeField] private float rightSpawnX = 10f; [SerializeField] private float spawnRange = 1f; [SerializeField] private float minX, maxX, distance = 0.5f; BuildingBehaviour[] buildings; BuildingBehaviour currentBuilding; bool[] buildingsBuilt; int currentBuildingIdx = 0; bool buildActive = false; int buildCount = 0; public Vector3 MoveDir { get; set; } = Vector3.zero; void Start() { buildings = GetComponentsInChildren<BuildingBehaviour>(); buildingsBuilt = new bool[buildings.Length]; minX = Mathf.Min(minX, leftSpawnX - spawnRange); maxX = Mathf.Max(maxX, rightSpawnX + spawnRange); ui.UpdateDistance(distance); EventManager.Instance.AddListener(EVENT_TYPE.ON_BUILDING_BUILT, this); EventManager.Instance.AddListener(EVENT_TYPE.ON_BUILDING_DISTANCE_CHANGED, this); Invoke("SetupNewBuild", 0.5f); } private void Update() { if (buildActive) { float step = buildingMoveSpeed * Time.deltaTime; if (currentBuilding != null) { Vector3 t = currentBuilding.building.position; t = Vector3.Lerp(t, t + MoveDir, step); t.x = Mathf.Clamp(t.x, minX, maxX); currentBuilding.building.position = t; } } } private void SetupNewBuild() { do { currentBuildingIdx = Random.Range(0, buildings.Length); } while (buildingsBuilt[currentBuildingIdx]); currentBuilding = buildings[currentBuildingIdx]; float startX = leftSpawnX; if (UnityEngine.Random.value > 0.5f) startX = rightSpawnX; currentBuilding.Init(startX + UnityEngine.Random.Range(-1f, 1f) * spawnRange); buildActive = true; } public void OnBuildingMoved(InputAction.CallbackContext ctx) { MoveDir = new Vector3(ctx.ReadValue<Vector2>().x, 0, 0); } public void OnBuildingConfirmed(InputAction.CallbackContext ctx) { if (ctx.performed && buildActive) { currentBuilding.CheckDistance(distance); } } public void OnBuildingRotated(InputAction.CallbackContext ctx) { if (ctx.performed && buildActive) { currentBuilding.Rotate(); } } public void OnEvent<T>(EVENT_TYPE eventType, Component Sender, T param = default) { switch (eventType) { case EVENT_TYPE.ON_BUILDING_BUILT: buildActive = false; buildingsBuilt[currentBuildingIdx] = true; buildCount++; if (buildCount < buildings.Length) { Invoke("SetupNewBuild", buildDelay + 1); } else { EventManager.Instance.PostNotification<Object>(EVENT_TYPE.ON_BUILDING_WON, this); } break; case EVENT_TYPE.ON_BUILDING_DISTANCE_CHANGED: distance = (dynamic)param; break; } } #if UNITY_EDITOR private void OnValidate() { ui.UpdateDistance(distance); } #endif }