<Prefabs>
Prefabs은 일종의 오브젝트를 모아놓은 상자라고 생각하면 됩니다. Project창에서 Create -> New Folder로 폴더 생성 후, Prefabs란 이름으로 명명합니다. Unity에서 Profabs 이름의 폴더는 따로 기능이 들어간 폴더로 간주합니다. 위 그림에서 장난감 역할로 넣어놓은 P_Ball 오브젝트가 Prefabs 폴더에 넣으면 이제 이 오브젝트는 필요할 때마다 코드를 통해 복사체(클론)를 생성하여 사용할 수 있습니다.
- 그냥 Hierarcy 창에서 오브젝트 소환해서 쓰면 안돼? 왜 굳이 그렇게 해야해?
그 이유는 여러 Scene에서 유연하게 사용할 수 있기 때문입니다.
Scene을 여러 개 사용하는 게임을 개발할 때 Hierarcy창에 똑같은 속성을 가진 오브젝트를 계속 만들어야하는 귀찮은 작업을 Prefabs에 넣어놓은 오브젝트들을 꺼내 사용하는 것으로 작업 효율을 크게 증가시켜줍니다. 그리고 앞써 복사체(클론)라고 언급했는데 Prefabs 폴더 안의 오브젝트를 Hierarcy창에 꺼내와서 막 변환시켜도 원본은 오브젝트는 변하지 않습니다. 혹여나 실험한다고 막 바꿨다가 기존 속성값을 잃어버리는 불상사를 방지할 수도 있습니다.
<Stack, Queue추가>
Stack과 Queue를 기억하시나요?
기본적인 개념 등을 이해하기 위해서 이전에 썼던 글을 참고해주시는 것도 좋을 것 같습니다. 간단히 설명하면
- Stack: 데이터 선입후출
- Queue: 데이터 선입선출
예를 들어 Prefabs를 이용하여 World에 1개씩 5개를 랜덤한 위치에 소환하였다고 가정해보겠습니다.
- Stack에 저장한 상태에서 1개씩 순서대로 Destroy할 시: 5 4 3 2 1 순서로 파괴
- Queue에 저정한 상태에서 1개씩 순서대로 Destroy할 시: 1 2 3 4 5 순서로 파괴
이제 오브젝트 생성하고 Stack, Queue에 저장한 후, 삭제하여 두 데이터의 특징을 알아보겠습니다.
using UnityEngine;
public class DataSvDt : MonoBehaviour
{
[SerializeField] private GameObject ballPrefab = null; //직접 Inspector창을 통해 가져오는 방법
private GameObject loadBallPrefab = null; //Load기능을 활용하여 Prefab을 가져오기 위한 변수
private Stack<GameObject> stack = new Stack<GameObject>();
private Queue<GameObject> queue = new Queue<GameObject>();
private void Start()
{
loadBallPrefab = (GameObject)Resources.Load("Prefabs\\P_Ball");
loadBallPrefab = Resources.Load("Prefabs\\P_Ball") as GameObject;
loadBallPrefab = Resources.Load<GameObject>("Prefabs\\P_Ball");
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
GameObject ballGo = Instantiate(ballPrefab,
Vector3.zero, Quaternion.identity, trasnform);
GameObject ballGo = Instantiate(ballPrefab,
Random.insideUnitySphere * 5f, Quaternion.identity, trasnform);
queue.Enqueue(ballGo);
stack.Push(ballGo);
}
if(Input.GetKeyDown(KeyCode.D))
{
GameObject go = null;
if(queue.TryDequeue(out go))
Destroy(go);
if(stack.TryPop(out go))
Destroy(go);
}
}
}
Load 키워드에 대한 코드 3줄을 알아봅시다. 물론 셋 중 하나만 사용하면 됩니다. 이건 설명용으로 같은 기능의 코드를 3개 만들어놓은 것입니다.
- loadBallPrefab = (데이터형)폴더이름.Load("폴더이름\\오브젝트 이름"); : Resources 폴더 내의 Prefabs폴더 안에 있는 P_Ball 오브젝트를 BallPrefab에 정의하라는 뜻
- loadBallPrefab = 폴더이름.Load("폴더이름\\오브젝트이름") as 데이터형; : Resources 폴더 내의 Prefabs폴더 안에 있는 P_Ball 오브젝트를 GameObject형태로 변환하여 BallPrefab에 정의하라는 뜻
- loadBallPrefab = 폴더이름.Load<데이터형>("Prefabs\\P_Ball"); : Resources 폴더 내의 Prefabs폴더 안에 있는 P_Ball 오브젝트를 GameObject형태로 변환하여 BallPrefab에 정의하라는 뜻
이제 오브젝트 생성 함수를 해석하겠습니다.
1. A를 누르면 ballGo라는 이름의 게임 오브젝트형 오브젝트를 생성하여 ballPrefab으로 지정된 오브젝트를, 원점 위치에, 기본회전(회전없이)으로 인스턴스화하고, 이 인스턴스는 transform 부모의 자식으로 생성됩니다. 여기서 부모는 이 스크립트를 가지고 있는 오브젝트가 됩니다.
2. A를 누르면 ballGo라는 이름의 게임 오브젝트형 오브젝트를 생성하여 ballPrefab으로 지정된 오브젝트를, 구의 안쪽에 위치한 5f 반경의 좌표에서 무작위 위치에, 기본회전(회전없이)으로 인스턴스화하고, 이 인스턴스는 transform 부모의 자식으로 생성됩니다. 여기서 부모는 위와 같습니다.
3. Enqueue로 ballGo 오브젝트를 큐에 추가합니다.
4. Push로 ballGo 오브젝트를 스택에 추가합니다.
이제 오브젝트 파괴 함수를 해석하겠습니다.
- GameObject의 go 변수는 null로 초기화합니다.
- 큐에 go라는 오브젝트가 있다면 TryDequeue로 그걸 꺼내려고 시도합니다.
- 꺼내는데 성공했다면 그 오브젝트를 파괴합니다.
- 스택에 go라는 오브젝트가 있다면 Try로 그걸 꺼내려고 시도합니다.
- 꺼내는데 성공했다면 그 오브젝트를 파괴합니다.
- 여기서 스택은 선입후출, 큐는 선입선출 방식입니다.
'유니티(Unity) 프로그래밍' 카테고리의 다른 글
코루틴 (Coroutine)을 통한 Picking (5) | 2024.10.03 |
---|---|
Unity 카메라 (1) | 2024.09.29 |
Unity Collider(Trigger, Collision) (2) | 2024.09.24 |
Unity 충돌감지 (1) | 2024.09.20 |
유니티3D 아날로그 시계 (0) | 2024.09.19 |