유니티 기초

몬스터 죽으면 아이템 생성

노재두내 2023. 8. 10. 13:19
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemController : MonoBehaviour
{
    [SerializeField]
    private GameEnums.eItemType itemType;

    public GameEnums.eItemType ItemType
    {
        get
        {
            return this.itemType;
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

하나씩 나오게 하는게 어려움

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test3
{
    public class Test_CreatePortalMain : MonoBehaviour
    {
        [SerializeField]
        private MonsterGenerator monsterGenerator;
        private List<MonsterController> monsterList;
        [SerializeField]
        private ItemGenerator itemGenerator;
        private List<ItemController> itemList;
        [SerializeField]
        private GameObject portalPrefab;
        
        
        // Start is called before the first frame update
        void Start()
        {
            this.monsterList = new List<MonsterController>();
            MonsterController turtle = this.monsterGenerator.Generate(GameEnums.eMonsterType.Turtle,new Vector3(-3,0,0));//제너레이터야 만들어라
            MonsterController slime = this.monsterGenerator.Generate(GameEnums.eMonsterType.Slime, new Vector3(0, 0, 3));

            this.monsterList.Add(turtle);
            this.monsterList.Add(slime);
            Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);
            foreach (MonsterController monster in monsterList)
            {
                Debug.LogFormat("monster{0}", monster);
            }
            this.itemList = new List<ItemController>();
            
            //ItemController potion = this.itemGenerator.Generate(GameEnums.eItemType.Potion, new Vector3(turtle.transform.position.x,turtle.transform.position.y,turtle.transform.position.z));
            //ItemController sword= this.itemGenerator.Generate(GameEnums.eItemType.Sword, new Vector3(slime.transform.position.x, slime.transform.position.y, slime.transform.position.z));
            //this.itemList.Add(potion);
            //this.itemList.Add(sword);
        }
        
        // Update is called once per frame
        void Update()
        {
            
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 3f);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, 100f))
                {
                    if (hit.collider.tag == "Monster")
                    {
                        
                        MonsterController controller =hit.collider.gameObject.GetComponent<MonsterController>();
                        this.monsterList.Remove(controller);
                        Destroy(hit.collider.gameObject);
                        this.itemGenerator.Generate(GameEnums.eItemType.Potion, new Vector3(hit.transform.position.x, hit.transform.position.y, hit.transform.position.z));
                        this.itemGenerator.Generate(GameEnums.eItemType.Sword, new Vector3(hit.transform.position.x, hit.transform.position.y, hit.transform.position.z));
                        
                        Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);

                    }
                    
                    int x = Random.Range(-4, 4);
                    int z = Random.Range(-4, 4);
                    if (this.monsterList.Count <= 0)
                    {
                        GameObject portalGo=Instantiate(portalPrefab);
                        portalGo.transform.position = new Vector3(x, 0, z);
                    }
                }
            }
            
        }
    }
}
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemGenerator : MonoBehaviour
{
    [SerializeField]
    private List<GameObject> itemList;
    private Vector3 monsterPosition;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public ItemController Generate(GameEnums.eItemType itemType,Vector3 monsterposition)
    {
        int index = (int)itemType;

        GameObject prefab = this.itemList[index];
        GameObject itemGo = Instantiate(prefab);

        
        itemGo.transform.position = monsterposition;

        return itemGo.GetComponent<ItemController>();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameEnums 
{
   public enum eMonsterType
    {
        Turtle,Slime
    }

    public enum eItemType
    {
        Potion,Sword
    }
}

+아이템 컨트롤러

-> 일단 태그 두개 만들기로 생각(돌아가긴 함) 근데 하드코딩? 인듯..

 if (hit.collider.tag == "Turtle")
                    {
                        
                        MonsterController controller =hit.collider.gameObject.GetComponent<MonsterController>();
                        this.monsterList.Remove(controller);
                        Destroy(hit.collider.gameObject);
                        this.itemGenerator.Generate(GameEnums.eItemType.Potion, new Vector3(hit.transform.position.x, hit.transform.position.y, hit.transform.position.z));
                        
                        
                        Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);

                    }
                    else if (hit.collider.tag == "Slime")
                    {
                        MonsterController controller = hit.collider.gameObject.GetComponent<MonsterController>();
                        this.monsterList.Remove(controller);
                        Destroy(hit.collider.gameObject);
                        this.itemGenerator.Generate(GameEnums.eItemType.Sword, new Vector3(hit.transform.position.x, hit.transform.position.y, hit.transform.position.z));
                        Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);

                    }

 

강사님 방법

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test3
{
    public class Test_CreatePortalMain : MonoBehaviour
    {
        [SerializeField]
        private MonsterGenerator monsterGenerator;
        private List<MonsterController> monsterList;
        [SerializeField]
        private ItemGenerator itemGenerator;
        private List<ItemController> itemList;
        [SerializeField]
        private GameObject portalPrefab;


        // Start is called before the first frame update
        void Start()
        {
            this.monsterList = new List<MonsterController>();
            MonsterController turtle = this.monsterGenerator.Generate(GameEnums.eMonsterType.Turtle, new Vector3(-3, 0, 0));//제너레이터야 만들어라
            turtle.onDie = (rewardItemType) =>
            {
                var pos = turtle.gameObject.transform.position;
                this.CreateItem(rewardItemType, pos);
                Destroy(turtle.gameObject);
            };
            MonsterController slime = this.monsterGenerator.Generate(GameEnums.eMonsterType.Slime, new Vector3(0, 0, 3));
            slime.onDie = (rewardItemType) =>
            {
                var pos = slime.gameObject.transform.position;
                this.CreateItem(rewardItemType, pos);
                Destroy(slime.gameObject);
            };
            this.monsterList.Add(turtle);
            this.monsterList.Add(slime);
            Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);
            foreach (MonsterController monster in monsterList)
            {
                Debug.LogFormat("monster{0}", monster);
            }
            this.itemList = new List<ItemController>();


        }

        // Update is called once per frame
        void Update()
        {

            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 3f);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, 100f))
                {

                    MonsterController controller = hit.collider.gameObject.GetComponent<MonsterController>();
                    if (controller != null)
                    {
                        this.monsterList.Remove(controller);
                        controller.Die();
                    }
                    

                    Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);

                }

                if (this.monsterList.Count <= 0)
                {
                    this.CreatePortal();
                }
            }


        }
        private void CreateItem(GameEnums.eItemType itemType, Vector3 position)
        {
            this.itemGenerator.Generate(itemType, position);
        }
        private void CreatePortal()
        {
            int x = Random.Range(-4, 4);
            int z = Random.Range(-4, 4);
            GameObject portalGo = Instantiate(portalPrefab);
            portalGo.transform.position = new Vector3(x, 0, z);
        }
    }
}
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test3
{
    public class ItemGenerator : MonoBehaviour
    {
        [SerializeField]
        private List<GameObject> itemList;
        private Vector3 monsterPosition;
        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {

        }
        public ItemController Generate(GameEnums.eItemType itemType, Vector3 monsterposition)
        {
            int index = (int)itemType;

            GameObject prefab = this.itemList[index];
            GameObject itemGo = Instantiate(prefab);


            itemGo.transform.position = monsterposition;

            return itemGo.GetComponent<ItemController>();
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test3
{
    public class MonsterController : MonoBehaviour
    {
        private Animator anim;
        public GameEnums.eItemType rewardItemType;

        public System.Action<GameEnums.eItemType> onDie;
        // Start is called before the first frame update
        void Start()
        {
            this.anim = this.GetComponent<Animator>();
        }

        // Update is called once per frame
        void Update()
        {

        }
        public void Die()
        {
            StartCoroutine(this.CoDie());
        }
        private IEnumerator CoDie()
        {
            this.anim.SetInteger("State", 3);
            yield return new WaitForSeconds(2.0f);
            this.onDie(this.rewardItemType);
        }
    }
}

죽는 위치에서 원하는 아이템을 설정하는것이 어려웠는데 

update에서 turtle이 죽은 위치를 불러오자니 어려웠다-> 근데 대리자를 통해서 start에서 위치를 설정할 수 있었음\