Skip to content

9 ‐ MapManager

문현우 edited this page Sep 13, 2023 · 2 revisions

📌 MapManager

🎇 Managed by 맹주한

  • 타일 매핑을 관리하는 기능을 담당합니다.

📜 Code Summary

  • Start()

    • PlaceRandomTiles() 메서드를 호출하여 무작위 타일을 배치합니다.

    • PlaceAndRemoveTiles() 코루틴을 시작하고 PlaceRockTiles() 함수를 repeatInterval마다 호출합니다.

  • PlaceRandomTiles()

    • 주어진 반경 내의 모든 타일을 무작위 타일로 배치합니다.
  • PlaceRockTiles()

    • 반경의 절반인 prevRadiusB를 계산합니다.

    • prevRadiusB와 radiusB의 차이인 radiusDifference를 계산합니다.

    • radiusDifference가 0보다 크면,

    • 반경 내의 모든 타일을 null로 설정하고, prevRadiusB보다 반경이 작은 모든 타일을 rockTile로 설정합니다.

    • rockTile의 콜라이더를 설정하고, rockTile 오브젝트를 생성하고, rockPosition에 배치합니다.

    • 마지막으로 5초 후에 rockObject를 제거합니다.

    • 이후 circleDiameterB를 1 감소시킵니다.

    • 반경이 0이 되면 PlaceRockTiles() 메서드를 더 이상 호출하지 않습니다.

  • PlaceAndRemoveTiles()

    • PlaceAndRemoveTiles() 코루틴은 shouldRemoveTiles가 true이면

    • 반경의 절반인 halfDiameter를 계산합니다.

    • 이후, 반경 내의 4개의 타일을 null로 설정합니다.

    • WaitForSeconds(repeatInterval * 1f) 함수를 호출하여 repeatInterval마다 대기합니다.

    • shouldRemoveTiles가 false가 되면, 이 코루틴은 중단됩니다.

  • GetRandomTileWithBias(TileBase[] tileArray, int biasedTileIndex, float bias)

    • bias가 0보다 크면, biasedTileIndex 인덱스의 타일을 반환합니다.
    • bias가 0보다 작거나 같으면, 0부터 tileArray.Length까지의 임의의 인덱스의 타일을 반환합니다.

💻 Code

MapManager.cs
using System.Collections;
using UnityEngine;
using UnityEngine.Tilemaps;

public class MapManger : MonoBehaviour
{
    public Tilemap tilemap;
    public TileBase[] tiles;
    public TileBase rockTile;
    public int circleDiameterA = 5;
    public int circleDiameterB = 6;
    public GameObject objectToPlaceTilesAt;
    public GameObject TestRockPrefab;
    public float repeatInterval = 5.0f;
    private bool shouldRemoveTiles = true;

    private void Start()
    {
        PlaceRandomTiles();
        StartCoroutine(PlaceAndRemoveTiles());
        InvokeRepeating("PlaceRockTiles", 0.0f, repeatInterval);
    }

    void PlaceRandomTiles()
    {
        int radiusA = circleDiameterA / 2;
        Vector3 centerPositionA = objectToPlaceTilesAt.transform.position;

        for (int x = -radiusA; x <= radiusA; x++)
        {
            for (int y = -radiusA; y <= radiusA; y++)
            {
                Vector3Int tilePositionA = new Vector3Int(x, y, 0);
                float distanceA = Vector3.Distance(tilePositionA + centerPositionA, centerPositionA);

                if (distanceA <= radiusA)
                {
                    TileBase randomTile = GetRandomTileWithBias(tiles, 0, 0.9f);
                    tilemap.SetTile(tilePositionA, randomTile);
                }
            }
        }
    }
    TileBase GetRandomTileWithBias(TileBase[] tileArray, int biasedTileIndex, float bias)
    {
        if (Random.value < bias)
        {
            return tileArray[biasedTileIndex];
        }
        else
        {
            int randomIndex = Random.Range(0, tileArray.Length);
            return tileArray[randomIndex];
        }
    }

    void PlaceRockTiles()
{
    int radiusB = circleDiameterB / 2;
    Vector3 centerPositionB = objectToPlaceTilesAt.transform.position;

    if (circleDiameterB >= 0)
    {
        int prevRadiusB = (circleDiameterB + 1) / 2;

        int radiusDifference = prevRadiusB - radiusB;

        if (radiusDifference > 0)
        {
            for (int x = -prevRadiusB; x <= prevRadiusB; x++)
            {
                for (int y = -prevRadiusB; y <= prevRadiusB; y++)
                {
                    Vector3Int tilePositionB = new Vector3Int(x, y, 0);
                    float distanceB = Vector3.Distance(tilePositionB + centerPositionB, centerPositionB);

                    if (distanceB > radiusB)
                    {
                        tilemap.SetTile(tilePositionB, null);

                        if (distanceB <= prevRadiusB)
                        {
                            tilemap.SetTile(tilePositionB, rockTile);
                            tilemap.SetTileFlags(tilePositionB, TileFlags.None);
                            tilemap.SetColliderType(tilePositionB, Tile.ColliderType.Grid);

                            Vector3 rockPosition = tilemap.GetCellCenterWorld(tilePositionB);
                            GameObject rockObject = Instantiate(TestRockPrefab, rockPosition, Quaternion.identity);

                            StartCoroutine(DestroyAfterDelay(rockObject, 5.0f));
                        }
                    }
                }
            }
        }

        circleDiameterB--;
    }
    else
    {
        CancelInvoke("PlaceRockTiles");
    }
}
    private IEnumerator PlaceAndRemoveTiles()
    {
        while (shouldRemoveTiles)
        {
            int radiusB = circleDiameterB / 2;
            Vector3 centerPositionB = objectToPlaceTilesAt.transform.position;

            int targetX = 0;
            int targetY = 0;

            int halfDiameter = circleDiameterB / 2;

            tilemap.SetTile(new Vector3Int(targetX + halfDiameter + 3, targetY, 0), null);
            tilemap.SetTile(new Vector3Int(targetX - halfDiameter - 3, targetY, 0), null);
            tilemap.SetTile(new Vector3Int(targetX, targetY + halfDiameter + 3, 0), null);
            tilemap.SetTile(new Vector3Int(targetX, targetY - halfDiameter - 3, 0), null);

            yield return new WaitForSeconds(repeatInterval * 1f);
        }
    }
    public void StopTileRemoval()
    {
        shouldRemoveTiles = false;
    }

IEnumerator DestroyAfterDelay(GameObject obj, float delay)
{
    yield return new WaitForSeconds(delay);
    Destroy(obj);
}


}

Clone this wiki locally