eye-therapy-2 / Assets / Scripts / Builder / BuildingManager.cs
BuildingManager.cs
Raw
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
}