Загрузка данных


using UnityEngine;
using TMPro;

public class CubeController : MonoBehaviour
{
    [SerializeField] float rotationSpeed = 100f;
    [SerializeField] float jumpForce = 8f;
    [SerializeField] float raycastDistance = 0.8f;
    [SerializeField] LayerMask groundLayer;
    [SerializeField] TextMeshPro counterTxt;
    [SerializeField] int counter;
    [SerializeField] int step = 5;
    [SerializeField] int maxCubes = 300;
    private Rigidbody2D rb;
    private SpriteRenderer spriteRenderer;
    private bool isGrounded;
    private int birthFrame;

    static int cubeCount;
    static bool wallsCreated;

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
    static void ResetStatics()
    {
        cubeCount = 0;
        wallsCreated = false;
    }

    void Awake()
    {
        birthFrame = Time.frameCount;
        cubeCount++;
    }

    void OnDestroy()
    {
        cubeCount--;
    }

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        spriteRenderer = GetComponentInChildren<SpriteRenderer>();
        if (counterTxt == null)
            counterTxt = GetComponentInChildren<TextMeshPro>();

        if (!wallsCreated)
        {
            CreateWalls();
            wallsCreated = true;
        }

        ChangeColor();
        plsCount();
    }

    void Update()
    {
        RotateCube();
        CheckGrounded();

        // новый кубик в кадр появления не прыгает
        if (Time.frameCount == birthFrame) return;

        if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
        {
            Jump();
        }
    }

    void RotateCube()
    {
        // крутится только картинка, физика не меняется
        spriteRenderer.transform.Rotate(0, 0, rotationSpeed * Time.deltaTime);
    }

    void CheckGrounded()
    {
        //сверху методы RotateCube() Update() Start()
        Vector2 rayStart = transform.position;
        RaycastHit2D hit = Physics2D.Raycast(rayStart, Vector2.down, raycastDistance, groundLayer);
        if (hit.collider != null)
        {
            isGrounded = true;
        }
        else
        {
            isGrounded = false;
        }
        //снизу Jump() ChangeColor() plsCount()
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        // в нашем задании триггеров нет, метод оставлен как у препода
    }

    void Jump()
    {
        rb.linearVelocity = new Vector2(rb.linearVelocity.x, 0f);
        rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);

        counter += step;
        ChangeColor();
        plsCount();

        SpawnClone();
    }

    void ChangeColor()
    {
        spriteRenderer.color = Random.ColorHSV(0f, 1f, 0.7f, 1f, 0.8f, 1f);
        counterTxt.color = Random.ColorHSV(0f, 1f, 0.7f, 1f, 0.8f, 1f);
    }

    void plsCount()
    {
        counterTxt.text = counter.ToString();
    }

    // ---- дополнительно: новые кубики и стенки по краям экрана ----

    void SpawnClone()
    {
        if (cubeCount >= maxCubes) return;

        Camera cam = Camera.main;
        if (cam == null) return;

        Vector3 pos = cam.ViewportToWorldPoint(
            new Vector3(Random.Range(0.1f, 0.9f), Random.Range(0.5f, 0.9f), 10f));
        pos.z = 0f;

        Instantiate(gameObject, pos, Quaternion.identity);
    }

    void CreateWalls()
    {
        Camera cam = Camera.main;
        if (cam == null) return;

        float halfH = cam.orthographicSize;
        float halfW = halfH * cam.aspect;
        float thickness = 1f;
        float height = halfH * 6f;

        MakeWall("WallLeft", new Vector2(cam.transform.position.x - halfW - thickness / 2f, 0f), new Vector2(thickness, height));
        MakeWall("WallRight", new Vector2(cam.transform.position.x + halfW + thickness / 2f, 0f), new Vector2(thickness, height));
    }

    void MakeWall(string wallName, Vector2 pos, Vector2 size)
    {
        GameObject wall = new GameObject(wallName);
        wall.transform.position = pos;
        wall.AddComponent<BoxCollider2D>().size = size;
    }
}