Vector는 C++ 표준 라이브러리(Standard Template Library)에 있는 컨테이너로 사용자가 손쉽게 사용하기 위해 정의된 class입니다. Vector의 가장 큰 장점은 동적으로 원소를 추가할 수 있으며 크기가 자동으로 늘어난다는 점입니다. 쉽게 말해 크기가 가변적으로 변하는 배열이라고 할 수 있습니다. 속도적인 측면에서는 배열에 비해 떨어지지만 메모리를 효율적으로 관리할 수 있다는 장점이 있어 굉장히 많이 사용합니다. vector는 배열과 마찬가지로 원소들이 하나의 메모리 블록에 연속하게 저장됩니다. 그렇기에 원소가 추가되거나 삽입될 때 메모리 재할당이 발생할 수 있고 상당한 부하가 발생하게 된다는 점은 단점으로 꼽히고 있습니다.
(2) Vector 구조
vector를 생성하면 메모리 heap에 생성되며 동적 할당됩니다.
front() :첫 번째 원소 back() :마지막 원소 begin() : 첫번째 위치 end() :마지막의 다음 위치 size() :원소의 개수 capacity() :할당된 공간의 크기
size와 capacity가 따로 있는 이유
매번 새로운 원소가 들어올 때마다 새로운 메모리가 할당되는 것은 비효율적입니다. 그렇기에 vector는 새로운 원소가 벡터에 추가되면 메모리 공간을 추가적으로 할당되는 방식으로 이루어져 있습니다. 좀 더 정확하게는 capacity가 모자랄 경우 capacity/2 만큼의 capacity를 늘려나가게 됩니다. 만약 입력될 원소의 개수를 알 수 있다면 reserve를 사용하여 미리 capapcity 메모리를 할당해 놓으면 좀 더 호율적으로 vector를 사용할 수 있습니다.
인스턴스화하는 데 특히 비용이 많이 드는 많은 수의 개체로 작업해야하고 각 개체가 짧은 시간 동안 만 필요한 경우 전체 응용 프로그램의 성능이 저하를 해결하기 위한 디자인 패턴이며 오브젝트를 생성 / 삭제를 반복하지 않으며 생성 한 오브젝트를 가지고 재사용 하는 방식
(2) Object를 이용한 코드 (Unity Tutorial)
총알생성을 Object Pool로구현
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour
{
//ttruen this class into a singleton for easy accessbility.
private static PoolManager _instance;
public static PoolManager Instance
{
get
{
if (_instance == null)
Debug.LogError("The PoolManager is NULL.");
return _instance;
}
}
[SerializeField]
private GameObject _bulletContainer;
[SerializeField]
private GameObject _bulletPrefab;
[SerializeField] //List로 관리
private List<GameObject> _bulletPool;
private void Awake()
{
_instance = this;
}
private void Start()
{
_bulletPool = GenerateBullets(10);
}
//pregenerate a list of bullets using the bullet prefab
List<GameObject> GenerateBullets(int amountOfBullets)
{
for (int i = 0; i < amountOfBullets; i++)
{
GameObject bullet = Instantiate(_bulletPrefab);
bullet.transform.parent = _bulletContainer.transform;
bullet.SetActive(false);
_bulletPool.Add(bullet);
}
return _bulletPool;
}
public GameObject RequestBullet()
{
//loop through the bullet list
//현재 Hierarchy 창에 활성화가 되지 않은 Object를 찾음
foreach (var bullet in _bulletPool)
{
if (bullet.activeInHierarchy == false)
{
//bullet is available
bullet.SetActive(true);
return bullet;
}
}
//List의모든 Object가 활성화시 새로 생성
//need to create a new bullet
GameObject newBullet = Instantiate(_bulletPrefab);
newBullet.transform.parent = _bulletContainer.transform;
_bulletPool.Add(newBullet);
return newBullet;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField]
private GameObject _bulletPrefab;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
//communicate with the object pool system
//Request Bullet
GameObject bullet = PoolManager.Instance.RequestBullet();
bullet.transform.position = Vector3.zero;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
private void OnEnable()
{
Invoke("Hide", 1);
}
void Hide()
{
//re-cycle the gameObject
this.gameObject.SetActive(false);
Debug.Log("Hiding GameObject");
}
}