Unity

[Unity] Top View Shooting Game Demo - pooling, dither(3)

Guk-blog 2020. 3. 17. 17:16
728x90
반응형

드디어 풀링입니다

왜이렇게 질질 끌었냐? 라고 물으신다면

제 답변은 "다들 그러던데용"

광고 노출때문이겠죠 뭐

먹고 삽시다 같이

ㅎㅎㅎㅎ

 

잡담은 이만하고 

 

풀링 스크립트 쏴드리겠습니다

 

우선 오브젝트 구성은 저렇게구요

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바깥은 없습니다

(총알이 부족하면 같이 생성하기 때문)

==============================================

 

순서가 엉망 진창인데

제가 원래 그런 놈이니 그러려니 해주시고

다음 편에서 계속 진행하겠습니다

728x90
반응형