[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 2]

※ 주의 

이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.



Menu

0. 미리보기

1. 오브젝트를 미리 생성.

- 프리팹 제작.

- 싱글톤 제작.

- 오브젝트를 생성시킬 함수 제작.

- 오브젝트를 찾을 함수를 제작.

2. 만들어진 오브젝트 활용하기.





2. 만들어진 오브젝트 활용하기.


- 총알 발사하기.

 * 총알을 발사하는 키로는 스페이스바로 하자.
 * 스페이스바를 한 번 눌렀다 땠을 때, 한 번만 발사된다.
 * 스페이스바를 게속 누르고 있으면 총알이 연속해서 발사된다. (코루틴을 이용한다.)
 * 총알이 발사되는 과정은 이렇다.
   - 비활성화인 총알을 리스트에서 찾아서 가져온다.
   - 총알의 위치를 설정한다.
   - 총알의 회전 상태를 설정한다.
   - 총알 객체를 활성화 시킨다.
   - 총알을 움직인다.


위의 과정을 수행하기 위해서 'Player'스크립트에 3개의 함수를 만들거다.

첫 번째 함수는 입력버튼을 감지하는 'KeyCheck()' 함수.
두 번째 함수는 연속 버튼을 수행하는 'NextFire()' 코루틴 함수.
세 번째 함수는 총알 정보를 셋팅하는 'BulletInfoSetting()' 함수.

그리고 총알을 움직여주기 위한 구문은 Bullet객체에 새로운 스크립트 'Bullet'을 만들어 수행하도록 하자.
이 스크립트에서는 총알을 움직여주기 위한것 뿐만 아니라, 총알을 재활용하기 위한 비활성화 구분도 수행될 것이다.


'Player Script'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Player : MonoBehaviour {
 
    public float Speed;         // 움직이는 스피드.
    public float AttackGap;     // 총알이 발사되는 간격.
 
    private Transform Vec;      // 카메라 벡터.
    private Vector3 MovePos;    // 플레이어 움직임에 대한 변수.
 
    private bool ContinuouFire; // 게속 발사할 것인가? 에 대한 플래그.
 
    void Init()
    {
        //공개.
        AttackGap = 0.2f;
 
        // 비공개
        MovePos = Vector3.zero;
        ContinuouFire = true;
    }
 
    void Start()
    {
        Vec = GameObject.Find("CameraVector").transform;
 
        Init();
    }
 
    void Update () 
    {
        Run();
        KeyCheck();
    }
 
    // 플레이어 움직임.
    void Run()
    {
        int ButtonDown = 0;
        if (Input.GetKey(KeyCode.LeftArrow))    ButtonDown = 1;
        if (Input.GetKey(KeyCode.RightArrow))   ButtonDown = 1;
        if (Input.GetKey(KeyCode.UpArrow))      ButtonDown = 1;
        if (Input.GetKey(KeyCode.DownArrow))    ButtonDown = 1;
 
        // 플레이어가 움직임 버튼에서 손을 땠을 때 Horizontal, Vertical이 0으로 돌아감으로써
        // 플레이어의 회전상태가 다시 원상태로 돌아가지 않게 하기 위해서.
        if (ButtonDown != 0)
            Rotation();
        else
            return;
 
        transform.Translate(Vector3.forward * Time.deltaTime * Speed * ButtonDown);
    }
 
    // 플레이어 회전.
    void Rotation()
    {
        MovePos.Set(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));   // 벡터 셋팅.
        Quaternion q = Quaternion.LookRotation(Vec.TransformDirection(MovePos));  // 회전
 
        if (MovePos != Vector3.zero)
            transform.rotation = q;
    }
 
    // 총알 키 체크.
    void KeyCheck()
    {
        if (Input.GetButtonDown("Jump"))
            StartCoroutine("NextFire");
        else if (Input.GetButtonUp("Jump")) 
            ContinuouFire = false;
    }
 
    // 연속발사.
    IEnumerator NextFire()
    {
        ContinuouFire = true;
        while (ContinuouFire)
        {
            // 총알을 리스트에서 가져온다.
            BulletInfoSetting(ObjManager.Call().GetObject("Bullet"));
            yield return new WaitForSeconds(AttackGap);                    // 시간지연.
        }
    }
 
    // 총알정보 셋팅.
    void BulletInfoSetting(GameObject _Bullet)
    {
        if (_Bullet == nullreturn;
 
        _Bullet.transform.position = transform.position;                // 총알의 위치 설정
        _Bullet.transform.rotation = transform.rotation;                // 총알의 회전 설정.
        _Bullet.SetActive(true);                                        // 총알을 활성화 시킨다.
        _Bullet.GetComponent<Bullet>().StartCoroutine("MoveBullet");    // 총알을 움직이게 한다.
    }
}
 
cs




'Bullet Script'


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Bullet : MonoBehaviour {
 
    // 총알의 움직임 및 일정 시간뒤 비 활성화.
    IEnumerator MoveBullet()
    {
        float timer = 0;
        while (true)
        {
            timer += Time.deltaTime;    // 시간 축적
            if(timer > 2)               // 2초뒤 반복문을 빠져나간다.
                break;
 
            transform.Translate(Vector3.forward * Time.deltaTime * 40f);    // 총알을 움직인다.
            yield return null;
        }
 
        // 총알 비활성화.
        gameObject.SetActive(false);
    }
}
cs




결과