ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (24) 아이템으로 패배판정 & 아이템 획득 & 충돌판정
    Galaxy Ball/1. 멀티플레이 - 대전모드 2024. 5. 2. 17:37

    이번엔 아이템을 확실하게 짚고 넘어가보려고 한다. 지금까지는 단순하게 아이템의 기능구현에 대해서만 다뤘지만

    이번글에는 아이템 역시 일반 발사구체처럼 충돌판정이 일어나

    내구도를 깎기도, 패배판정을 내기도, 아이템 획득도 하도록 하겠다

     

    시작하기전에 간단한 수정부분을 한가지 적고 가겠다

     private void Update()
     {
         if (Input.GetMouseButtonDown(0))
         {
             clickPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
             clickPosition.z = 0f;
             Collider2D[] colliders = Physics2D.OverlapPointAll(clickPosition);
             foreach (Collider2D collider in colliders)
             {
                 if (P1FireMode && collider.gameObject == P1firezone)
                 {
                     if (fireitem != null)
                     {
                         fireitem.gameObject.tag = "P1Item";
                         Instantiate(fireitem, clickPosition, Quaternion.identity);
                         Debug.Log("P1이 아이템을 사용하였습니다");
                         Debug.Log("아이템의 이름은 " + fireitem.gameObject.name + "입니다");

    GameManager 스크립트 중 Firezone에서 클릭했을시 구체를 생성하는 기능을 구현하는 일부이다

    이제 어느 Firezone에서 클릭했냐에 따라

    fireitem.gameObject.tag = "P1Item";

    각각의 소속된 태그가 실시간으로 정해진다

     

    ---------------------------------------------------------------------------------------

    <충돌판정> 

    그동안은 기본구체가 부딫힐때만 충돌판정이 일어나고 패배판정이 되었었다

    이번엔 내가 발사하는 아이템들도 충돌과 패배판정이 일어나도록 해보겠다

     

    좀 더 까다로운 패배판정부터 시작해보자. 패배판정의 조건은 이렇다

    "내가 날린 구체가 팽창되기 전의 상태에서 본인의 Deadzone에 닿았을때"

    총 3가지의 조건이 있다

    1. 내가 날린 구체가

    2. 팽창되기 전 상태로

    3. 내 Deadzone에 충돌

     

    그래서 나는 게임 오브젝트의 태그를 이용하여 이 조건을 만족시켰었다

    하지만 아이템의 갯수는 더 많고 각각의 기능이 다르기에 그 안에 들어가는 코드들도 전부 제각각이다

    그렇기에 이번에는 태그에다 오브젝트 이름까지 이용하여 패배판정을 구현해보겠다

     

    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class P1Deadzone : MonoBehaviour
    {
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "P1ball")
            {
                BallController ball = collision.GetComponent<BallController>();
                if (!ball.hasExpanded)
                    SceneManager.LoadScene("P2 Win");
            }
        }
    }

     

    패배 판정을 결정하는 P1Deadzone 스크립트. 여기에 코드를 추가해보겠다

     

    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class P1Deadzone : MonoBehaviour
    {
        public bool isExpand;
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "P1ball")
            {
                BallController ball = collision.GetComponent<BallController>();
                if (!ball.hasExpanded)
                    SceneManager.LoadScene("P2 Win");
            }
    
    
            if (collision.gameObject.tag == "P1Item")
            {
                switch (collision.gameObject.name)
                {
                    case "BlackHoleF(Clone)":
                        BlackHole_Skill skill = collision.GetComponent<BlackHole_Skill>();
                        this.isExpand = skill.hasExpanded;
                        break;
                    case "DurabilityF(Clone)":
                        Durability_Skill skill2 = collision.GetComponent<Durability_Skill>();
                        this.isExpand = skill2.hasExpanded;
                        break;
                    case "FastenF(Clone)":
                        Fasten_Skill skill3 = collision.GetComponent<Fasten_Skill>();
                        this.isExpand = skill3.hasExpanded;
                        break;
                    case "ForceF(Clone)":
                        Force_Skill skill4 = collision.GetComponent<Force_Skill>();
                        this.isExpand = skill4.hasExpanded;
                        break;
                    case "InvincibleF(Clone)":
                        Invincible_Skill skill5 = collision.GetComponent<Invincible_Skill>();
                        this.isExpand = skill5.hasExpanded;
                        break;
                    case "Random_numberF(Clone)":
                        Random_number_Skill skill6 = collision.GetComponent<Random_number_Skill>();
                        this.isExpand = skill6.hasExpanded;
                        break;
                    case "ReductionF(Clone)":
                        Reduction_Skill skill7 = collision.GetComponent<Reduction_Skill>();
                        this.isExpand = skill7.hasExpanded;
                        break;
                }
                if (isExpand == false)
                {
                    SceneManager.LoadScene("P2 Win");
                }
            }
        }
    }

     

    public class P1Deadzone : MonoBehaviour
    {
        public bool isExpand;

        bool타입 변수 isExpand 선언

    .......... 

     

    if (collision.gameObject.tag == "P1Item")

     첫번째 조건은 Deadzone에 부딫힌 오브젝트의 태그가 P1Item이어야 한다
            {
                switch (collision.gameObject.name)

        Switch문으로 그 오브젝트의 이름을 가져온다
                {
                    case "BlackHoleF(Clone)":

                   만약 이름이 "BlackHoleF(Clone)이라면
                        BlackHole_Skill skill = collision.GetComponent<BlackHole_Skill>();

                        skill 변수에 해당 컴포넌트 정보를 가져온다
                        this.isExpand = skill.hasExpanded;

                        그리고 isExpand 에 변수 skill의 hasExpanded 정보를 넣어준다

                        (*hasExpanded : 구체 확장의 유무를 저장하는 변수)
                        break;
                     .........
                }
                if (isExpand == false)

                만약 이때 가져온 값이 false라면
                {
                    SceneManager.LoadScene("P2 Win");

                    패배 판정
                }
            }

    물론 이게 최선의 방법이 아니라는건 알고 있지만 지금 내 실력에서 머리를 싸매고 있느니

    내가 할수 있는 방법을 뭐라도 써서 진행을 시키는게 훨씬 나을것같아 이렇게 진행시키기로 했다

     

     

     

    이제 아이템이 Deadzone에 닿아도 패배판정이 일어나는 것을 확인할 수 있다

    -----------------------------------------------------------------------

    <아이템 획득>

    이번엔 아이템으로 아이템을 획득할수 있도록 해보겠다. 사실 이건 복잡할게 없다

    public class GetItem : MonoBehaviour
    {
        public AudioSource GetItemSound;
        private void OnTriggerEnter2D(Collider2D collision)
        {
            Rigidbody2D otherRigidbody = collision.gameObject.GetComponent<Rigidbody2D>();
            if ((collision.gameObject.tag == "P1ball" || collision.gameObject.tag == "P1Item") && otherRigidbody != null)
            {
                string destroyedObjecttag = gameObject.tag;
                ShowP1ItemIcon itemIconScript = FindObjectOfType<ShowP1ItemIcon>();
                itemIconScript.PrintDestroyedObjectTag(destroyedObjecttag);
                Debug.Log("P1이 아이템 " + destroyedObjecttag + "를 획득했습니다");
                Destroy(gameObject);
            }
            if((collision.gameObject.tag == "P2ball" || collision.gameObject.tag == "P2Item") && otherRigidbody != null)
            {
                string destroyedObjecttag = gameObject.tag;
                ShowP2ItemIcon itemIconScript = FindObjectOfType<ShowP2ItemIcon>();
                itemIconScript.PrintDestroyedObjectTag(destroyedObjecttag);
                Debug.Log("P2가 아이템 " + destroyedObjecttag + "를 획득했습니다");
                Destroy(gameObject);
            }
        }
    }

     

    아이템과 구체가 닿을때 아이템은 삭제하고 아이템 태그정보를 넘겨주는 스크립트 GetItem

    여기에 조건을 하나만 더 달아주면 된다

     

    if ((collision.gameObject.tag == "P1ball" || collision.gameObject.tag == "P1Item") && otherRigidbody != null)
    충돌한 물체의 태그가 P1ball 뿐만 아니라 P1Item 태그까지 가능하게 만들어주면 된다

     

     

     

    ------------------------------------------------------------------

     

    마지막으로 충돌판정이다. 구체끼리 충돌이 일어나면 내구도가 닳아야하는데 

    구체와 아이템끼리의 충돌도 내구도 충돌이 일어나게 구현해보겠다

     

     private void OnCollisionEnter2D(Collision2D coll)
     {
         if (!hasExpanded)
         {
            HitSound.Play();
         }
         if ((coll.gameObject.tag == "P1ball" || coll.gameObject.tag == "P2ball" || coll.gameObject.tag == "P1Item" || coll.gameObject.tag == "P2Item") && rigid == null)
         {
             if (randomNumber > 0)
             {
                 randomNumber--;
                 textMesh.text = randomNumber.ToString();
             }
             if (randomNumber <= 0)
             {
                 Destroy(gameObject);
             }
         }

    팽창이 끝나버린 상태에서 충돌이 일어났을때 다른 오브젝트와 충돌시 내구도(randomNumber)를 줄여버리는 GameManager 스크립트의 일부이다

     

         if ((coll.gameObject.tag == "P1ball" || coll.gameObject.tag == "P2ball" || coll.gameObject.tag == "P1Item" || coll.gameObject.tag == "P2Item") && rigid == null)

     

    이 조건에 P1Item과 P2Item도 추가해주면 된다

     

     

    이로써 아이템이 다른 구체와 충돌시 내구도도 깎아먹고, 다른 아이템 획득도 하고, 패배판정까지 이루어내는것을

    확인할 수 있다

     

    ------------------------------------------------------------

    여기서 글을 끝내려했는데 생각난게 있어 짜잘한 부분들을 몇개 더 수정했다

     

    가장 먼저 블랙홀 아이템.

    팽창만 끝난 상태라면 어떤 구체든 가리지 않고 닿는 즉시 파괴시켜버리는 아이템으로써

     private void OnCollisionEnter2D(Collision2D coll)
     {
         if (!hasExpanded)
         {
             HitSound.Play();
         }
    
         if ((coll.gameObject.tag == "P1ball" || coll.gameObject.tag == "P2ball" || coll.gameObject.tag == "P1Item" || coll.gameObject.tag == "P2Item") && rigid == null)
         {
             Destroy(coll.gameObject);
         }

    블랙홀 기능구현을 담당하는 스크립트에 닿은 오브젝트를 파괴하는 조건에 P1Item, P2Item 태그를 추가시켜주자

    사실 처음에 보고 어차피 안가리고 죄다 파괴하는거라면 조건을 걸지않고

    Destroy(coll.gameObject)만 남겨두면 되는거 아닌가? 라는 생각이 들었었는데

    이렇게 되면 말그대로 닿는 모든것을 파괴하기 때문에 Deadzone을 비롯한

    주변틀로 맞춰둔 Box Collider까지 전부 삭제시켜버리게 된다

     

    다른 아이템 기능들도 마찬가지이다. 일일이 다 쓰기엔 너무 길어져 생략하지만 다른 아이템 기능구현 스크립트에도

    조건에 태그 P1Item과 P2Item을 추가해주었다

     

     

Designed by Tistory.