일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ChatGPT
- HAPTIC
- 유니티 Json 데이터 연동
- 연습
- 유니티 UI
- 앱 배포
- meta xr
- input system
- XR
- 드래곤 플라이트
- 개발
- 오큘러스
- Photon Fusion
- OVR
- 오브젝트 풀링
- VR
- 가상현실
- 팀프로젝트
- CGV
- 유니티
- 모작
- Oculus
- 포트폴리오
- 멀티플레이
- 드래곤 플라이트 모작
- meta
- 길건너 친구들
- 개발일지
- 팀 프로젝트
- 유니티 GUI
- Today
- Total
EasyCastleUNITY
드래곤 플라이트 모작 개발일지2 (총알발사와 오브젝트 풀링) 본문
총알발사
오브젝트 풀링을 적용해보기 전에,
총알을 특정시기마다 복제하고 발사하는 방식을 먼저 구현해보겠습니다.
이 시점 부터는 GameScene 자체를 관리하는
GameMain을 만들고 최상위에 두는 구조로 만들어 보겠습니다.
전 포스트에서 작성한 플레이어와 드래곤도 GameMain에서 관리합니다.
총알을 발사할때마다 복제하고 발사하는 기능 구현 (오브젝트 풀링 사용 X)
Bullet -> 총알 자체의 움직임을 제어하는 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
private float moveSpeed;
// Start is called before the first frame update
void Start()
{
this.moveSpeed = 10.0f;
}
// Update is called once per frame
void FixedUpdate()
{
this.transform.Translate(Vector2.up * this.moveSpeed * Time.deltaTime);
this.SelfDestroy();
}
//테스트
private void SelfDestroy()
{
if (this.transform.position.y > 5.86f)
{
Destroy(this.gameObject);
Debug.Log("<color=red>총알 삭제</color>");
}
}
}
BulletGenerator -> 총알을 생성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletGenerator : MonoBehaviour
{
[SerializeField]
private Transform bulletInitPos; // 총알 생성 위치
private float elapsedTime = 0.0f; //경과시간
[SerializeField] private float intervelTime = 0.3f;
[SerializeField] private GameObject bulletPrefab;
public void Shoot()
{
this.elapsedTime += Time.deltaTime;
if(this.elapsedTime > intervelTime)
{
GameObject go =Instantiate(this.bulletPrefab);
go.transform.position = this.bulletInitPos.position;
this.elapsedTime = 0.0f;
}
}
}
GameMain -> 게임 씬 전체를 관리
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameMain : MonoBehaviour
{
[SerializeField] private Player player;
[SerializeField] private Dragon[] dragons;
[SerializeField] private BulletGenerator bulletGenerator;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
this.bulletGenerator.Shoot();
}
}
총알의 생성위치는 빈 오브젝트를 생성하여, 플레이어의 자식으로 만들어서,
플레이어가 움직이면, 총알의 생성위치도 같이 움직이도록 하였습니다.
오브젝트 풀링
위에 방식으로 만들면, 만드는 순간마다 메모리를 사용하게 됨으로 성능의 저하를 일으킵니다.
그래서 이를 해결하기 위해 실행하는 순간에 미리 총알을 만들어 두고,
그 총알들을 불러오는 오브젝트 풀링을 구현하려고 합니다.
BulletPoolManager -> 만들어둔 총알들을 관리하는 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletPoolManager : MonoBehaviour
{
//총알을 미리 생성해 저장할 리스트
[SerializeField]
private List<GameObject> bulletPool = new List<GameObject>();
//오브젝트 풀에 생성할 총알의 최대 개수
[SerializeField] private int maxBullets = 10;
//싱글톤 인스턴스 선언
public static BulletPoolManager instance = null;
//총알 프리팹
[SerializeField] private GameObject bulletPrefab;
#region 속성
public List<GameObject> BulletPool { get => bulletPool; }
#endregion
private void Awake()
{
if(instance == null)
{
instance = this;
}
else if(instance != null)
{
Destroy(this.gameObject);
}
// 아직 게임 씬만 구성하지만
// 추후에 새로운 씬도 추가할 수 있도록 사용
DontDestroyOnLoad(gameObject);
}
private void Start()
{
this.CreateBulletPool();
}
//실행시 총알 만들기
private void CreateBulletPool()
{
for(int i=0; i<maxBullets; i++)
{
GameObject bulletGo = Instantiate(this.bulletPrefab);
bulletGo.SetActive(false);
bulletGo.transform.SetParent(this.transform);
bulletPool.Add(bulletGo);
}
}
//풀에서 총알 받아가기
public GameObject GetBulletInPool()
{
foreach(GameObject bullet in this.bulletPool)
{
//활성화 상태가 아니면 받아옴
if (bullet.activeSelf == false)
{
return bullet;
}
}
return null;
}
//돌아오기
public void ReleaseBullet(GameObject bulletGo)
{
bulletGo.SetActive(false);
bulletGo.transform.SetParent(this.transform);
}
}
BulletGenerator -> 총알을 풀에서 받아오고 발사하는 스크립트,
풀에서 만들어둔 총알이 부족할 경우, 동적으로 생성하고 리스트에 추가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletGenerator : MonoBehaviour
{
[SerializeField]
private Transform bulletInitPos; // 총알 생성 위치
private float elapsedTime = 0.0f; //경과시간
[SerializeField] private float intervelTime = 0.3f;
[SerializeField] private GameObject bulletPrefab;
public void Shoot()
{
this.elapsedTime += Time.deltaTime;
if(this.elapsedTime > intervelTime)
{
this.CallBullet();
this.elapsedTime = 0.0f;
}
}
private void CallBullet()
{
GameObject go = BulletPoolManager.instance.GetBulletInPool();
if (go == null) //이미 만들어둔 총알을 다 사용하면
{
go = Instantiate(this.bulletPrefab);
BulletPoolManager.instance.BulletPool.Add(go);
go.transform.position = this.bulletInitPos.position;
Debug.Log("<color=cyan>총알 동적 생성</color>");
}
else if(go != null) //이미 만들어둔 총알이라면
{
go.transform.SetParent(null); //매니저 밖으로 나옴
go.transform.position = this.bulletInitPos.position;
go.SetActive(true); // false였으니 true로 변환
}
}
}
Bullet -> 총알 자체의 움직임을 담당하는 스크립트, 일정 범위를 넘어가면 풀로 되돌아간다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
private float moveSpeed;
// Start is called before the first frame update
void Start()
{
this.moveSpeed = 10.0f;
}
// Update is called once per frame
void FixedUpdate()
{
this.transform.Translate(Vector2.up * this.moveSpeed * Time.deltaTime);
this.SelfComeback();
}
//테스트
private void SelfComeback()
{
if (this.transform.position.y > 5.86f)
{
Debug.Log("<color=yellow>총알 풀로 되돌아감</color>");
BulletPoolManager.instance.ReleaseBullet(this.gameObject);
}
}
}
메인은 동일합니다.
이번 개발일지에서는 총알을 동적으로 생성하여 발사하는 방법과, 오브젝트 풀링을 적용하는 방법을 해보았습니다.
다음 개발일지에서는 총알과 드래곤의 충돌처리를 다루겠습니다.
'2D 프로젝트 개발 일지(드래곤 플라이트 모작)' 카테고리의 다른 글
드래곤 플라이트 모작 개발일지6 (드래곤 오브젝트 풀링 및 웨이브 만들기) (0) | 2023.09.14 |
---|---|
드래곤 플라이트 모작 개발일지5(드래곤이 죽으면, 그 자리에 아이템 생성) (0) | 2023.09.14 |
드래곤 플라이트 모작 개발일지4 (드래곤 사망시 이펙트 구현) (0) | 2023.09.14 |
드래곤 플라이트 모작 개발일지3 (총알과 드래곤 충돌처리 및 배경 스크롤링) (0) | 2023.09.13 |
드래곤 플라이트 모작 개발일지1 (플레이어 이동 및 충돌처리) (0) | 2023.09.13 |