Skip to content

develop Drop System

Jeon-YJ1004 edited this page Mar 10, 2023 · 5 revisions

파괴 가능한 오브젝트 구현

  1. 오브젝트 생성
    오성혁 develop-Tile 참고

  2. 프리펩에 DestructibleObject.cs와 DropSystem.cs 추가.
    예시로 아래는 체력템을 50%확률로 드랍하고, 코인을 50% 확률로 드랍.
    image

  3. 파괴가능한 오브젝트는 IDamageable 상속=> TakeDamage 함수 오버라이딩.

public class DestructibleObject : MonoBehaviour,IDamageable
{

   public void TakeDamage(float damage)
    {
        //position 위치에 Drop 생성
        gameObject.GetComponent<DropSystem>().OnDrop(gameObject.transform.position);
        Destroy(gameObject);
    }
}

드롭 시스템 구현

세팅사항

  • PoolMangager의 적 Prefabs에 DropSystem.cs 컴포넌트 추가
  • 몬스터 마다 경험치 Drops 설정
    image
  • InGame.scene에 Drop 객체를 생성해주는 빈 객체 생성
    image
  • Drop도 Enemy처럼 Pooling 사용하기

로직:

  1. 적 object가 destroy되면 0~100중 랜덤하게 수 생성
  2. randomNumber가 Drops의 dropRate보다 낮으면 드롭가능 리스트에 추가 ex) exp를 90%로 드롭하는데 randomNumber가 30이 나왔다=> 경험치 드롭할 수 있다.
  3. 드롭 가능 리스트는(posibleDrops) 드롭할 수 있는 아이템이 여러개일 때 사용. ex) 횃불을 파괴 후 나올 수 있는 아이템은 치킨, 코인 등 여러개이다.
  4. posibleDrops에서 랜덤하게 드롭할 아이템 선택
  5. dropsObj에 위치와 이름으로 GetComponent().Spawn 5.1 Spawn함수는 Enemy Spawn과 로직이 같다. 5.2 PoolManager에 사용할 종류별로 프리펩 배열을 만들어 따로 관리한다
    image

5.3 switch문으로 Get할 프리펩을 지정한다.

[PoolManager.cs]
.
.
.
 public GameObject Get(string type,int index) //게임 오브젝트 반환 함수
    {
        switch (type)//drop하고 싶은 오브젝트 이름 
        {
            case "enemy":
                targetPool = enemyPools;
                targetPrefab = enemyPrefabs;
                break;
            case "exp":
                targetPool = expPools;
                targetPrefab = expPrefabs;
                break;

            case "heart":
                targetPool = heartPools;
                targetPrefab = heartPrefabs;
                Debug.Log("heart pooling");
                break;

            case "coin":
                targetPool = coinPools;
                targetPrefab = coinPrefabs;
                Debug.Log("coin pooling");
                break;
        }
        GameObject select = null;
        //선택한 풀의 비활성화 된 게임 오브젝트 접근.
        // 발견하면 select 변수에 할당
        
        foreach (GameObject item in targetPool[index])
        {
            if (!item.activeSelf)
            {
                select = item;
                select.SetActive(true);
                break;
            }
        }
        // 못찾으면 새롭게 생성후 할당// 모든 적이 죽지 않고 살아있음
        if (!select)
        {
            select = Instantiate(targetPrefab[index], transform);
            targetPool[index].Add(select);
        }
        return select;
    }

[DropSystem.cs]
public class DropSystem : MonoBehaviour
{
    public GameObject dropsObj;
    [System.Serializable]
    public class Drops
    {
        public string name;
        public int prefabsIndex;
        public float dropRate;
    }
    
    public List<Drops> drops;
     public void OnDrop(Vector2 pos)
    {
        //로직 1. 적이 죽으면 랜덤 넘버 생성(아이템 확률)
        float randomNumber = UnityEngine.Random.Range(0f, 100f);
        dropsObj = GameObject.Find("--DropObj--");
        //로직 3.
        List<Drops> posibleDrops = new List<Drops>();
        foreach(Drops rate in drops)
        {   
            //로직 2
            if (randomNumber <= rate.dropRate) posibleDrops.Add(rate);
        }       
        //drop possible 인지 확인
        if (posibleDrops.Count > 0)
        {   
            //로직 4.
            Drops drops = posibleDrops[UnityEngine.Random.Range(0, posibleDrops.Count)];
            dropsObj.GetComponent<DropSpawner>().Spawn(transform.position,drops.name, drops.prefabsIndex);
        }
    }
}

[DropSpawner.cs]
public class DropSpawner : MonoBehaviour
{
    public void Spawn(Vector2 pos,string name, int index)
    {
        GameObject newDrops = GameManager.instance.pool.Get(name, index);
        newDrops.transform.position = pos;
        newDrops.transform.parent = transform;
    }
}
Clone this wiki locally