[Unity 2D] 일정 주기마다 랜덤 위치에 오브젝트 스폰

Jangmanbo·2021년 11월 28일
1

일정 주기마다 맵에 게임 오브젝트를 생성하고 삭제하기를 반복하는 기능을 구현하고자 한다. 추가적으로 플레이어가 오브젝트에 닿으면 오브젝트를 비활성화하고 특정 작업을 수행한다.




  1. 스폰하고자 하는 게임 오브젝트를 Assets/Prefabs에 저장한다.

  1. scene에 Empty object를 생성한다.
    나는 책을 스폰할 것이기 때문에 BookSpawnManager라 지었다.


  1. BookSpawnManager에 Box Collider 2D component를 추가한다.
    size로 오브젝트를 생성하고자 하는 범위를 지정하면 된다.


  1. BookSpawnManager 오브젝트에 같은 이름의 스크립트를 생성한다.
    Box Collider 2D로 지정한 범위 안에서 일정 주기마다 원하는 개수의 게임 오브젝트를 생성하고 삭제할 것이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BookSpawnManager : MonoBehaviour
{
    public GameObject book;

    int count = 10;                 //생성할 책(게임 오브젝트)의 개수
    private BoxCollider2D area;     //BoxCollider2D의 사이즈를 가져오기 위한 변수
    private List<GameObject> bookList = new List<GameObject>();		//생성한 책 오브젝트 리스트

    void Start()
    {
        area = GetComponent<BoxCollider2D>();
        StartCoroutine("Spawn", 20);
    }

    //게임 오브젝트를 복제하여 scene에 추가
    private IEnumerator Spawn(float delayTime)
    {
        for (int i = 0; i < count; i++) //count만큼 책 생성
        {
            Vector3 spawnPos = GetRandomPosition(); //랜덤 위치 return

            //원본, 위치, 회전값을 매개변수로 받아 오브젝트 복제
            GameObject instance = Instantiate(book, spawnPos, Quaternion.identity);
            bookList.Add(instance); //오브젝트 관리를 위해 리스트에 add
        }
        area.enabled = false;
        yield return new WaitForSeconds(delayTime);   //주기 : 20초

        for (int i = 0; i < count; i++) //책 삭제
            Destroy(bookList[i].gameObject);

        bookList.Clear();           //bookList 비우기
        area.enabled = true;
        StartCoroutine("Spawn", 20);    //책 다시 스폰
    }

    //BoxCollider2D 내의 랜덤한 위치를 return
    private Vector2 GetRandomPosition()
    {
        Vector2 basePosition = transform.position;  //오브젝트의 위치
        Vector2 size = area.size;                   //box colider2d, 즉 맵의 크기 벡터

        //x, y축 랜덤 좌표 얻기
        float posX = basePosition.x + Random.Range(-size.x / 2f, size.x / 2f);
        float posY = basePosition.y + Random.Range(-size.y / 2f, size.y / 2f);

        Vector2 spawnPos = new Vector2(posX, posY);

        return spawnPos;
    }

}

Vector3 spawnPos = GetRandomPosition();

GetRandomPosition() : Box Collider 내의 랜덤한 위치를 Vector2 타입으로 반환한다.


GameObject instance = Instantiate(book, spawnPos, Quaternion.identity);

Instantiate : 원본, 생성할 위치, 회전값을 매개변수로 한다. 원본에는 아까 만든 Prefabs나 scene에 존재하는 게임 오브젝트를 넣어주면 된다.
Quaternion.identity : 기본값 (회전 X)


yield return new WaitForSeconds(delayTime);
StartCoroutine("Spawn", 20);

게임 시작 시 오브젝트를 생성하고 일정 주기마다 삭제와 생성을 반복하고자 한다. 따라서 IEnumerator 인터페이스를 사용하여 게임 오브젝트가 리스폰되는 주기를 파라미터로 넣으면 된다.






알림창 띄우기

나는 이렇게 플레이어가 책 오브젝트와 충돌하면 오브젝트를 비활성화하고 책을 찾았다는 알림창을 띄우는 기능도 추가하였다.

void OnCollisionEnter2D(Collision2D coll)
    {
        if (coll.gameObject.name == "Book(Clone)") {	//부딪힌 오브젝트가 책인 경우
            coll.gameObject.SetActive(false);	//Book Object 비활성화
            /*
            	알림창 띄우기
            */
        }
    }

OnCollisionEnter2D 함수를 플레이어 오브젝트의 스크립트에 추가하면 된다.
OnCollisionEnter2D는 물리적 충돌을 감지하므로 두 오브젝트 모두 collider 컴포넌트가 있어야 하고 둘 중 하나는 rigidbody도 있어야 한다.






결과

참고자료
https://angliss.cc/random-gameobject-created/

2개의 댓글

comment-user-thumbnail
2021년 11월 28일

코드에 언어 인식 좀 시켜주세요. 코드 읽기가 힘듭니다.

답글 달기
comment-user-thumbnail
2021년 12월 4일

md로 작성하는거면

```언어
[코드]
```

이렇게 작성하면 언어 하이라이팅이 가능합니다.

```javascript
console.log("hello, world")
```
console.log("hello, world")
답글 달기