Unity2D_Basic #4

haechi·2021년 7월 21일
0

unity

목록 보기
25/39

210721
Unity2D_Basic #4


  • Instantiate() 활용

중첩 반복문을 사용해서 원하는 모양으로 오브젝트를 배치, 생성을 할 수 있다.

ObjectSpawner.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectSpawner : MonoBehaviour
{
    [SerializeField]
    private GameObject boxPrefab;

    private void Awake()
    {
        // 외부 반복문 (격자의 y축)
        for (int y = 0; y < 10; ++y)
        {
            // 내부 반복문 (격자의 x축)
            for (int x = 0; x < 10; ++x)
            {
                if(x == y || x+y == 9)
                {
                    continue;
                }
                
                Vector3 position = new Vector3(-4.5f + x, 4.5f - y, 0);

                Instantiate(boxPrefab, position, Quaternion.identity);
            }
        }
    }
}

  • 임의의 prefab으로 오브젝트 생성

1.circle, triangle prefab을 만들기

2.ObjectSpawner.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    private 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], position, Quaternion.identity);
        }
    }
}

int value = Random.Range(int min, int max);
min부터 max-1까지 정수 중에서 임의의 숫자를 value에 저장

float value = Random.Range(float min, float max);
위와 동일 정수 -> 실수

3.prefabArray 수 입력 후 prefab 지정

실행 화면

매 실행마다 임의의 prefab을 골라서 생성

  • 임의의 위치에서 오브젝트 생성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectSpawner : MonoBehaviour
{
    [SerializeField]
    private int objectSpawnCount = 30;
    [SerializeField]
    private GameObject[] prefabArray;

    private void Awake()
    {
       for (int i = 0; i < objectSpawnCount; ++i)
        {
            int index = Random.Range(0, prefabArray.Length);
            float x = Random.Range(-7.5f, 7.5f);    // x 위치
            float y = Random.Range(-4.5f, 4.5f);    // y 위치
            Vector3 position = new Vector3(x, y, 0);

            Instantiate(prefabArray[index], position, Quaternion.identity);
        }
    }
}

지정한 개수 만큼 임의의 위치에 생성

  • SpawnPoint에서 오브젝트 생성
    1.빈 오브젝트를 생성 후 SpawnPoint1,2 로 지정 후 배치

    2.ObjectSpawner 수정
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectSpawner : MonoBehaviour
{
    [SerializeField]
    private int objectSpawnCount = 30;  // 생성 할 오브젝트의 개수
    [SerializeField]
    private GameObject[] prefabArray;   // prefab의 배열
    [SerializeField]
    private Transform[] spawnPointArray;    // 위치값을 가진다

    private void Awake()
    {
       for (int i = 0; i < objectSpawnCount; ++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);
        }
    }
}

point 지정

실행 시 한 점으로 모여서 생성 되어서 정확한 확인이 어렵다.

  • 확인을 위해 움직이도록 한다.
    Movement2D.cs 수정
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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;
    }
}

ObjectSpawner.cs 수정

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectSpawner : MonoBehaviour
{
    [SerializeField]
    private int objectSpawnCount = 30;  // 생성 할 오브젝트의 개수
    [SerializeField]
    private GameObject[] prefabArray;   // prefab의 배열
    [SerializeField]
    private Transform[] spawnPointArray;    // 위치값을 가진다
    private int currentObjectCount = 0; // 현재까지 생성한 오브젝트 개수
    private float objectSpawnTime = 0.0f;

    private void Update()
    {

        if(objectSpawnCount < currentObjectCount + 1)   // 최대 생성 개수만큼 생성할 수 있도록
        {
            return;
        }

        // 원하는 시간마다 오브젝트 생성하도록 하는 연산
        objectSpawnTime += Time.deltaTime;  // 실제 초와 동일하게 실행
        
        // 0.5초마다 실행
        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);

            // spawnIndex가 1 -> 오브젝트가 왼쪽에 있기 때문에 오른쪽으로 이동
            Vector3 moveDirection = (spawnIndex == 1 ? Vector3.right : Vector3.left);
            clone.GetComponent<Movement2D>().Setup(moveDirection);

            currentObjectCount++;   // 현재 오브젝트 개수 증가
            objectSpawnTime = 0.0f; // 시간 초기화 -> 0.5초를 계산을 위해서
        }
    }
}

각 prefab에 Movement2D 컴포넌트로 추가


각 위치에서 0.5초 간격으로 생성이 되는 것을 확인할 수 있다.

이를 슈팅게임에 적용해서 활용한다고 생각해보자
플레이어가 특정 버튼을 눌렀을때 생성하도록 하게 한다면?

player 오브젝트를 생성 -> playercontroller.cs 생성
-PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    // Update is called once per frame
    void Update()
    {
        // 플레이어 오브젝트 이동
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

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

        // bullet 발사
        if (Input.GetKeyDown(keyCodeFire))  // 버튼을 누르면 실행
        {
            // clone을 생성 -> bulletPrefab을 생성, 현재 오브젝트의 위치
            GameObject clone = Instantiate(bulletPrefab, transform.position, Quaternion.identity);

            clone.name = "Bullet";
            clone.transform.localScale = Vector3.one * 0.5f;
            clone.GetComponent<SpriteRenderer>().color = Color.red;
        }
    }
}

실행시

위와 같이 해당 자리에서 생성만 된다.
이를 움직이도록 해보자

-PlayerController.cs 수정

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private KeyCode keyCodeFire = KeyCode.Space;
    [SerializeField]
    private GameObject bulletPrefab;
    private float moveSpeed = 3.0f;
    private Vector3 lastMoveDirection = Vector3.right;  // 마지막에 움직였던 방향, 최초에는 오른쪽으로 이동하도록 한다

    // Update is called once per frame
    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)
        {
            lastMoveDirection = new Vector3(x, y, 0);
        }

        // bullet 발사
        if (Input.GetKeyDown(keyCodeFire))  // 버튼을 누르면 실행
        {
            // clone을 생성 -> bulletPrefab을 생성, 현재 오브젝트의 위치
            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(lastMoveDirection);  // 저장한 방향을 Movement2D의 Setup()이라는 함수에 방향값을 전달
        }
    }
}

lastMoveDirection이 추가되었다. 마지막 이동 방향을 기억하여 방향키를 눌렀을 시 저장된 방향 값으로 총알이 발사되도록 한다.

참고
https://www.inflearn.com/course/%EA%B3%A0%EB%B0%95%EC%82%AC-%EC%9C%A0%EB%8B%88%ED%8B%B0-%EA%B8%B0%EC%B4%88/dashboard

profile
공부중인 것들 기록

0개의 댓글