210721
Unity2D_Basic #4
중첩 반복문을 사용해서 원하는 모양으로 오브젝트를 배치, 생성을 할 수 있다.
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);
}
}
}
}
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);
}
}
}
지정한 개수 만큼 임의의 위치에 생성
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 지정
실행 시 한 점으로 모여서 생성 되어서 정확한 확인이 어렵다.
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이 추가되었다. 마지막 이동 방향을 기억하여 방향키를 눌렀을 시 저장된 방향 값으로 총알이 발사되도록 한다.