드디어 풀링입니다
왜이렇게 질질 끌었냐? 라고 물으신다면
제 답변은 "다들 그러던데용"
헷
광고 노출때문이겠죠 뭐
먹고 삽시다 같이
ㅎㅎㅎㅎ
잡담은 이만하고
풀링 스크립트 쏴드리겠습니다
우선 오브젝트 구성은 저렇게구요
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pooling : MonoBehaviour
{
public static Pooling instance;
public Transform player;
[Header("bullet")]
public List<GameObject> bullets;
public GameObject bulletPrefab;
public Transform firePos;
public Transform bulletParent;
[Header("Paticle")]
public List<GameObject> particles;
public GameObject particlePrefab;
public Transform particleParent;
public float bulletForce =20f;
// Start is called before the first frame update
void Start()
{
instance = this;
Init(2);
StartCoroutine(CheckDistance());
}
void Init(int count)
{
Instantiate(count);
}
#region bullet
public void Instantiate(int count)
{
for (int i = 0; i < count; i++)
{
GameObject bullet = Instantiate(bulletPrefab, firePos.position, Quaternion.identity);
bullet.transform.parent = bulletParent;
bullets.Add(bullet);
bullet.SetActive(false);
GameObject effect = Instantiate(particlePrefab, transform.position, Quaternion.identity);
effect.transform.parent = particleParent;
particles.Add(effect);
effect.SetActive(false);
}
}
public void Shoot()
{
foreach (var bullet in bullets)
{
if (!bullet.activeInHierarchy)
{
bullet.transform.SetPositionAndRotation(firePos.position, Quaternion.identity);
bullet.SetActive(true);
Rigidbody rb= bullet.GetComponent<Rigidbody>();
rb.velocity = Vector3.zero;
rb.AddForce(firePos.forward * bulletForce, ForceMode.Impulse);
return;
}
}
Init(1);
Shoot();
}
public void BulletDisappear(GameObject g)
{
g.SetActive(false);
}
IEnumerator CheckDistance()
{
while (true)
{
if (bullets.Count > 0)
{
foreach (var bullet in bullets)
{
if (Vector3.Distance(player.position, bullet.transform.position) > 5f)
{
BulletDisappear(bullet);
}
}
}
yield return null;
}
}
#endregion bullet
#region particle
public void ShowParticle(Vector3 pos)
{
foreach (var particle in particles)
{
if (!particle.activeInHierarchy)
{
particle.transform.SetPositionAndRotation(pos, Quaternion.identity);
particle.SetActive(true);
return;
}
}
}
#endregion particle
}
========== 혹시나 코드 설명이 필요하신 분들을 위해========
풀링을 싱글톤으로 만든 이유는
Bullet이 instance로 생성되고 불릿이 오브젝트에 부딪힐 때 파티클을 실행시켜줘야 함으로 입니당
좋은 방법 아시면 공유점
Transform player =>은 총알과 거리에 따라 꺼주기 위해
List<GameObject> bullets => 풀링된 오브젝트 관리
GameObject bulletPrefab => 총알 프리팹
Transform firePos => 총알이 생성될 위치
Transform bulletParent => 하이라키에서의 총알 수용소
아래 헤더의 Paticle도 같은 이유입니다.
총알과 파티클을 생성하는 부분입니다.
List<GameObject> bullets를 순차적으로 돌면서 꺼져있는 쉑이 있으면
bullet.trans bullet.transform.SetPositionAndRotation(firePos.position, Quaternion.identity);
에서 포지션과 로테이션을 조정해주고
set true를 해줍니다
그리고 bullet에 붙어있는 rigidbody를 가져와서 addforce를 해줍니다
rd.AddForce(firePos.forward(앞으로 쏘겠다) * bulletForce(이 스피드로), ForceMode.Impulse(순간적으로);
만약 해당하는게 있다면 return;을 통해 해당 함수를 빠져나오고
만약 모두 켜져있다면 foreach단을 빠져나오고
Init(1)에서 새로 하나 뚝딱 만든 담에
다시 해당 함수를 실행합니다.
총알이 일정 거리 이상 멀어지면 오브젝트를 끄게 만드는 함수입니다.
코루틴을 사용할 때 반복함수를 사용할 때는
반드시 반복 함수 안에 yield return null을 사용해주세요
컴퓨터 울어요
ㅠㅠ
무튼 Vector3.Distance함수를 통해
player.posion, bullet의 포지션의 거리를 계산하고 5 이상이면 끈다는 말입니다.
파티클을 켜주는 함수입니다
총알과 같은 원리로 꺼져있는 놈찾아서 켜줍니다
여기선 개수가 부족할 리가 없기 때문에
foreach바깥은 없습니다
(총알이 부족하면 같이 생성하기 때문)
==============================================
순서가 엉망 진창인데
제가 원래 그런 놈이니 그러려니 해주시고
다음 편에서 계속 진행하겠습니다
'Unity' 카테고리의 다른 글
[Unity] Top View Shooting Game Demo - pooling, dither(5) (0) | 2020.03.17 |
---|---|
[Unity] Top View Shooting Game Demo - pooling, dither(4) (0) | 2020.03.17 |
[Unity] Top View Shooting Game Demo - pooling, dither(2) (0) | 2020.03.17 |
[Unity] Top View Shooting Game Demo - pooling, dither(1) (0) | 2020.03.17 |
[Unity] Mouse Look Script (0) | 2020.03.16 |