유니티

11. 장애물 랜덤 배치 C# 스크립트

MJ_119 2023. 6. 8. 17:29

기존에 작성한 GameController 스크립트에 수정을 한다.

 

using System.Collections;
using System.Collections.Generic; // List 클래스 사용 
using UnityEngine;

public class GameController : MonoBehaviour
{
    [Tooltip("생성하고자 하는 타일 참조")]
    public Transform tile;

    [Tooltip("생성하고자 하는 장애물 참조")] // 추가
    public Transform obstacle;
        
    [Tooltip("첫 번째 타일이 생성되는 곳")]
    public Vector3 startPoint = new Vector3(0,0,-5);

    [Tooltip("사전에 몇 개의 타일이 생성되어야 하는가")]
    [Range(1,15)]
    public int initSpawnNum = 6;

    [Tooltip("장애물 없이 생성되는 초반 타일들의 숫자")] // 추가
    public int initNoObstacle = 4;
    
    
    

    ///다음 타일이 생성되는 곳
    private Vector3 nextTileLocation;

    /// 다음 타일의 회전은?
    private Quaternion nextTileRotation;

    // Start is called before the first frame update
    void Start()
    {
        // 시작 포인트 설정
        nextTileLocation = startPoint;
        nextTileRotation = Quaternion.identity;
        
        for (int i = 0; i < initSpawnNum; i++)
        {
            SpawnNextTile(i >= initNoObstacle); // () 안에 i >= initNoObstacle 추가
        }
    }

    /// <summary>
    /// 특정 위치에 타일을 생성하고 다음 위치를 설정한다.
    /// </summary>
    /// <param name="spawnObstacles">장애물을 생성해야 하는가</param> // 추가

    public void SpawnNextTile(bool spawnObstacles = true) // ()안에 bool spawnObstacles = true 추가
    {
        var newTile = Instantiate(tile, nextTileLocation, nextTileRotation);

        // 다음 아이템을 생성할 위치와 회전 값을 알아낸다.
        var nextTile = newTile.Find("Next Spawn Point");
        nextTileLocation = nextTile.position;
        nextTileRotation = nextTile.rotation;
        
        if (spawnObstacles) // 추가
        {
            SpawnObstacles(newTile);
        }
    }

 // 아래쪽 추가
    private void SpawnObstacles(Transform newTile)
    {
        // 장애물을 생성할 수 있는 모든 위치가 필요
        var obstacleSpawnPoints = new List<GameObject>();

        // 타일의 모든 자식 게임 오브젝트를 확인
        foreach (Transform child in newTile)
        {
            // ObstacleSpawn 태그가 있는 경우
            if( child.CompareTag("ObstacleSpawn") )
            {
                // 장애물 생성이 가능한 곳으로 추가
                obstacleSpawnPoints.Add(child.gameObject);
            }
        }

        // 적어도 한 군데는 있는지 확인
        if (obstacleSpawnPoints.Count > 0)
        {
            // 확보한 곳들 중 하나를 무작위로 선택
            var spawnPoint = obstacleSpawnPoints[Random.Range(0, obstacleSpawnPoints.Count)];

            // 해당 위치를 사용할 수 있도록 저장
            var spawnPos = spawnPoint.transform.position;

            // 장애물 생성
            var newObstacle = Instantiate(obstacle, spawnPos, Quaternion.identity);

            // 타일을 부모로 지정
            newObstacle.SetParent(spawnPoint.transform);
        }
    }
}

이전 코드와 비교하면서 쭉 코드를 추가해주고 스크립트를 저장한다.

 

유니티 에디터에서 Game Controller 인스펙터창에 있는 Obstacle에 Obstacle 프리팹을 넣어주고 실행해서 확인해본다.

 

 

이것으로 대략적인 3D 공 굴리기 게임을 만들어 보았다.

 

수정하고 싶으면 여러가지 파라미터 값들을 수정해가면서 확인해보면 될것 같다.