본문 바로가기

Unity

Instantiate 활용 예제

반응형

prefab 여러 종류에 대해 랜덤 생성 가능

  • GameObject 배열 사용
public class PrefabTest : MonoBehaviour
{
	[SerializeField]
    private GameObject[] prefabArray;
    
    privat void Awake()
    {
    	for(int i = 0; i < 10; i++)
        {
        	int index = Random.Range(0, prefabArray.Length);
            Vector3 position = new Vector3(-4.5f + i, 0, 0);
            
            Instantiate(prefabArray[index], postioion, Quaternion.identity);
        }
    }
}

x,y 위치 또한 Random.Range(-4.5f , 4.5f) 와 같이 랜덤 생성 지정 가능

 

SpawnPoint

  • 오브젝트가 생성되는 기본 위치
  • 오브젝트가 생성될 위치 또한 지정 가능

Sample

Spawner

public class Spawner : MonoBehaviour
{
    [SerializeField]
    private GameObject[] prefabArray;

    [SerializeField]
    private Transform[] spawnPointArray;

    private float moveSpeed = 5.0f;
    private Vector3 moveDirection;

    private void Awake()
    {
        for(int i =0; i<10; i++)
        {
            int prefabIndex = Random.Range(0, prefabArray.Length);
            int spawnIndex = Random.Range(0, spawnPointArray.Length);

            Vector3 position = spawnPointArray[spawnIndex].position;
            GameObject clone = Instantiate(prefabArray[prefabIndex], position, Quaternion.identity);

            Vector3 moveDirection = (spawnIndex == 0 ? Vector3.right : Vector3.left);
            clone.GetComponent<Movement2D>().Setup(moveDirection);

        }
    }
}

Movement2D

public class Movement2D : MonoBehaviour
{
    private float moveSpeed = 5.0f;
    private Vector3 moveDirection;

    public void Setup(Vector3 direction)
    {
        moveDirection = direction;
    }

    private void Update()
    {
        transform.position += moveDirection * moveSpeed * Time.deltaTime;
    }
}

Spawner Object는 Prefab을 바탕으로 특정 위치에 Clone을 생성시켜주는 객체이고 movement의 실체는 Prefab들임

따라서 movement2D를 Spanwner에 script 지정해도 의미가 없음

또한 clone은 Prefab들로부터 만들어진 것이고 따라서 Prefab에 지정된 스크립트에서 가져와야 하는 것인데 Prefab에 지정되지 않은 스크립트 메소드의 파라미터를 참조하면 null 에러가 발생함

 

시간차를 두고 clone 생성 

deltaTime을 더해주면 게임 시간과 동일하게 흘러감

Sample

public class Spawn : MonoBehaviour
{
    [SerializeField]
    private int objectSpawnCount = 30;
    [SerializeField]
    private GameObject[] prefabArray;
    [SerializeField]
    private Transform[] spawnPointArray;
    private int currentObjectCount = 0;
    private float objectSpawnTime = 0.0f;

    private void Update()
    {
        if(currentObjectCount + 1 > objectSpawnCount)
        {
            return;
        }

        objectSpawnTime += Time.deltaTime;

        if(objectSpawnTime >= 0.5f)
        {
            int prefabIndex = Random.Range(0, prefabArray.Length);
            int spawnIndex = Random.Range(0, spawnPointArray.Length);

            Vector3 position = spawnPointArray[spawnIndex].position;
            GameObject clone = Instantiate(prefabArray[prefabIndex], position, Quaternion.identity);

            Vector3 moveDirection = (spawnIndex == 0 ? Vector3.right : Vector3.left);
            clone.GetComponent<Movement2D>().Setup(moveDirection);

            currentObjectCount++;
            objectSpawnTime = 0.0f;

        }

        
    }
}

 

총알을 발사하는 플레이어 예제

방향키에 따라 플레이어가 움직이도록 구현

Keycode가 space로 설정된 상태에서 Input이 Keycode인 경우 Bullet을 나타내는 Prefab 생성

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private KeyCode keyCodeFire = KeyCode.Space;
    [SerializeField]
    private GameObject bulletPrefab;
    private float moveSpeed = 3.0f;

    private void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

        transform.position += new Vector3(x, y, 0) * moveSpeed * Time.deltaTime;

        if(Input.GetKeyDown(keyCodeFire))
        {
            GameObject clone = Instantiate(bulletPrefab, transform.position, Quaternion.identity);
            clone.name = "Bullet";
            clone.transform.localScale = Vector3.one * 0.5f;
            clone.GetComponent<SpriteRenderer>().color = Color.red;
        }
    }
}

 

아무것도 누르지 않는 경우 x,y가 0인점을 이용하여 날아가는 총알 구현

movement2D를 Bullet에 적용

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private KeyCode keyCodeFire = KeyCode.Space;
    [SerializeField]
    private GameObject bulletPrefab;
    private float moveSpeed = 3.0f;
    private Vector3 lastMovedDirection = Vector3.right;

    private void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

        transform.position += new Vector3(x, y, 0) * moveSpeed * Time.deltaTime;

        if(x != 0 || y != 0)
        {
            lastMovedDirection = new Vector3(x, y, 0);
        }

        if(Input.GetKeyDown(keyCodeFire))
        {
            GameObject clone = Instantiate(bulletPrefab, transform.position, Quaternion.identity);
            clone.name = "Bullet";
            clone.transform.localScale = Vector3.one * 0.5f;
            clone.GetComponent<SpriteRenderer>().color = Color.red;
            clone.GetComponent<Movement2D>().Setup(lastMovedDirection);
        }
    }
}

 

반응형

'Unity' 카테고리의 다른 글

게임오브젝트 삭제 함수  (0) 2023.07.24
게임 오브젝트 생성 함수  (0) 2023.07.23
게임오브젝트 물리와 충돌  (0) 2023.07.23
게임 오브젝트 이동  (0) 2023.07.23
이벤트 함수  (0) 2023.07.23