ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (20) 아이템 #사용구현
    Galaxy Ball/1. 멀티플레이 - 대전모드 2024. 4. 8. 16:37
    구체 충돌 시 반사
    구체 정지 시 확장
    Deadzone
    Firezone
    발사 구현
    확장이 완료 시 고정 & 충돌 피해 X
    구체 내구도 부여 & 내구도 소진시 구체 파괴
    사운드 이펙트
    메인 화면 & 환경설정창
    턴제 시스템
    아이템 랜덤 생성 & UI
    아이템 기능 구현
    밸런스 조절

     

    맨 처음 짜두었던 R&D 목록이다. 아이템 기능구현을 제외한 모든 목록들을 끝낸것을 확인할 수 있다

     

    아이템이 대략 10개 정도 되니 10개의 기능들을 하나하나 전부 구현해야겠지만

    그 단계까지 필요한 과정들을 정리하고 시작하겠다

     

    1. 아이템 아이콘 클릭시 다음 생성 구체는 해당 아이템

    2. 한턴에 여러 아이템을 클릭해도 다음 생성 구체는 마지막으로 클릭한 아이템

    3. 어떠한 클릭도 없다면 기본구체 발사

     

    쉽게 말해 아이콘 클릭과 아이템 생성을 연계 시켜주고 아이템 기능구현을 해야할것이다

     

    아이콘 클릭 <=> 아이템 생성 : GameManager

    아이템 기능구현 : BallController

     

    각 기능을 담당하는 스크립트들이다. 우선 아이콘 클릭과 아이템 생성을 연계 시켜보겠다

     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ItemIconDestroy : MonoBehaviour
    {
        public IconAudioPlay iconAudioPlay;
        private Camera mainCamera;
        private RaycastHit2D hit;
        private void Start()
        {
            mainCamera = Camera.main;
        }
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
                hit = Physics2D.GetRayIntersection(ray);
    
                if (hit.collider != null && hit.collider.gameObject == gameObject)
                {
                    string destroyedicontag = hit.collider.gameObject.tag;
                    
                    //추가한 부분
                    Debug.Log("클릭한 아이콘의 태그 : " + destroyedicontag);
                    GameManager icontag = FindObjectOfType<GameManager>();
                    icontag.PrintDestroyedicontag(destroyedicontag);
                    Destroy(gameObject);
                }
            }
        }
    }

     

     

    위는 ItemIconDestroy 스크립트.

    즉 아이콘을 클릭했을때 아이콘을 삭제시킨뒤 아이템 사용을 활성화시키는 스크립트이다

                    코드의 후반부를 보게되면 아이콘을 클릭하는 순간
                    string destroyedicontag = hit.collider.gameObject.tag;
                    문자열 타입 변수 destroyedicontag는 마우스 클릭이 닿은 콜라이더(아이콘)의 태그 정보를 담아낸다
                    GameManager icontag = FindObjectOfType<GameManager>(); 
                    icontag이라는 변수에 GameManager 컴포넌트를 불러온 뒤                                
                    icontag.PrintDestroyedicontag(destroyedicontag);
                   GameManager에 있는 PrintDestroyicontag 메서드에 아이콘 태그값을 전달해주고
                    Destroy(gameObject);
                   아이콘을 삭제한다

    쉽게 말해 클릭한 아이콘의 태그값을 GamaManager 스크립트에 전달해주는 역할이다
    이제 본격적인 아이템 사용이 이뤄지는 GameManager를 살펴보자

     

    using System;
    using UnityEngine;
    
    public class GameManager : MonoBehaviour
    {
        public GameObject P1ballPrefab;
        public GameObject P2ballPrefab;
        
        //추가된 내용 1
        public GameObject[] FireItemPrefab;
    
        public GameObject P1firezone;
        public GameObject P2firezone;
        public GameObject P1Itemsave;
        public GameObject P2Itemsave;
        public GameObject fireitem;
    
        private Vector3 clickPosition;
        public bool isDragging = false;
        public static float shotDistance;
        public static Vector3 shotDirection;
    
        private bool P1FireMode = true;
        private bool P2FireMode = false;
    
        private void Start()
        {
            P1firezone.gameObject.SetActive(true);
            P2firezone.gameObject.SetActive(true);
        }
        
        //추가된 내용 2
        public void PrintDestroyedicontag(string icontag)
        {
            this.fireitem = null;
            switch (icontag)
            {
                case "Item_BlackHole":
                    fireitem = FireItemPrefab[0];
                    break;
                case "Item_Durability":
                    fireitem = FireItemPrefab[1];
                    break;
                case "Item_Fasten":
                    fireitem = FireItemPrefab[2];
                    break;
                case "Item_Five_Round":
                    fireitem = FireItemPrefab[3];
                    break;
                case "Item_Force":
                    fireitem = FireItemPrefab[4];
                    break;
                case "Item_Invincible":
                    fireitem = FireItemPrefab[5];
                    break;
                case "Item_Plus1":
                    fireitem = FireItemPrefab[6];
                    break;
                case "Item_Plus2":
                    fireitem = FireItemPrefab[7];
                    break;
                case "Item_Random_number":
                    fireitem = FireItemPrefab[8];
                    break;
                case "Item_Random_skill":
                    fireitem = FireItemPrefab[9];
                    break;
                case "Item_Reduction":
                    fireitem = FireItemPrefab[10];
                    break;
            }
        }
        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)
                    {
                        //추가된 내용 3-1
                        if (fireitem != null)
                        {
                            Instantiate(fireitem, clickPosition, Quaternion.identity);
                            P1FireMode = false;
                            P2FireMode = true;
                            isDragging = true;
                            P1firezone.gameObject.SetActive(false);
                            P2firezone.gameObject.SetActive(true);
                            P1Itemsave.gameObject.SetActive(false);
                            P2Itemsave.gameObject.SetActive(true);
                            break;
                        }
                        else
                        {
                            Instantiate(P1ballPrefab, clickPosition, Quaternion.identity);
                            P1FireMode = false;
                            P2FireMode = true;
                            isDragging = true;
                            P1firezone.gameObject.SetActive(false);
                            P2firezone.gameObject.SetActive(true);
                            P1Itemsave.gameObject.SetActive(false);
                            P2Itemsave.gameObject.SetActive(true);
                            break;
                        }
                    }
                    if (P2FireMode && collider.gameObject == P2firezone)
                    {
                        //추가된 내용 3-2
                        if (fireitem != null)
                        {
                            Instantiate(fireitem, clickPosition, Quaternion.identity);
                            P1FireMode = true;
                            P2FireMode = false;
                            isDragging = true;
                            P1firezone.gameObject.SetActive(true);
                            P2firezone.gameObject.SetActive(false);
                            P1Itemsave.gameObject.SetActive(true);
                            P2Itemsave.gameObject.SetActive(false);
                            break;
                        }
                        else
                        {
                            Instantiate(P2ballPrefab, clickPosition, Quaternion.identity);
                            P1FireMode = true;
                            P2FireMode = false;
                            isDragging = true;
                            P1firezone.gameObject.SetActive(true);
                            P2firezone.gameObject.SetActive(false);
                            P1Itemsave.gameObject.SetActive(true);
                            P2Itemsave.gameObject.SetActive(false);
                            break;
                        }
                    }
                }
            }
    
            if (isDragging && Input.GetMouseButtonUp(0))
            {
                Vector3 currentPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                currentPosition.z = 0f;
                GameManager.shotDistance = Vector3.Distance(clickPosition, currentPosition);
                Vector3 dragDirection = (currentPosition - clickPosition).normalized;
                GameManager.shotDirection = -dragDirection;
                isDragging = false;
            }
        }
    }

     

    추가된 내용은 보기 쉽게 주석을 달아주었다

    코드가 이렇게까지 길어지는게 맞나 싶지만 내 실력의 한계도 있고, 어쨋든 내가 원하는대로 구현만 되면 장땡이기에

    신경쓰지 않겠다

    추가된 내용1에서는 FireItemPrefab이라는 변수를 배열로 선언하여 직접 발사할 아이템에 사용될 프리팹들을 넣어주었다


    추가된 내용2을 보면 전 스크립트에서 만든 PrintDestroyedicontag라는 메서드를 추가한뒤
    클릭한 아이콘의 태그값을 담은 변수 icontag를 switch문에 집어넣는다
    그리고 이 태그값에 따라 몇번째 FireitemPrefab을 fireitem에 넣어줄지 결정한다

     

    추가된 3-1,3-2로 넘어가 이제 조건문을 한가지 더 걸어

    만약 fireitem이 null값이 아니라면(아이템을 사용한 상태라면) 기본 P1ballPrefab이 아닌 fireitem을 발사하도록 했다

     

     

    한번 실행을 해보자 아이템을 사용한 뒤 firezone에서 클릭하면 방금 클릭한 아이템 아이콘과 똑같은 이미지가 

    생성되는것을 확인할 수 있지만, 마우스를 잡아끌어당겨도 아이템이 날아가질 않는다

     

    당연히 발사용 이미지에는 어떠한 컴포넌트도 추가하지 않았기 때문. 

    여기에다 Rigidbody2D, Circle Collider2D, 그리고 이동과 팽창을 제어할 BallController도 추가해주자

     

    물론 BallController는 아이템이 정상적으로 날아가는지 확인을 위한 임시적인 추가이다

     

     

    이제 콜라이더에 스크립트까지 달아줬으니 다시 한번 확인해봤으나 날아가는것도 어설프고

    이런 오류들이 계속해서 뜨는것을 확인할 수 있다

    이게 뭔가 싶어 확인해보니

     

     

    사운드를 할당해주지 않아 다음 코드로 넘어갈수가 없다는 의미였다

    할당을 안해줬으면 그냥 이건 건너뛰고 다음 줄로 넘어가줄줄 알았지만

    이런것도 코드에서는 넘어가주지 않으니 참고하자

     

    물론 사운드까지 넣어줄수 있으나 어차피 난 아이템 프리팹이 날아가는것만 확인하면 되니 둘다 주석처리를 해주겠다

     

     

    이제 잘 날아가는것을 확인할 수 있다. 프리펩위에 쓰여진 숫자같은건 우선 무시하겠다

     

    이번글에서는 아이템을 획득시 생기는 아이콘을 클릭하면 다음 생성 구체는 해당 아이템으로 적용되도록 해보았다

    다음글에서는 본격적인 아이템의 기능구현을 시작해보도록 하겠다

     

    끝내기전 간략한 수정을 하나 해주자

     

    아이템 랜덤생성시 프리펩과 획득시 활성화되는 아이콘의 프리펩이 완전히 일치하여 인게임에서 구분이 가질 않아 헷갈린다

    아이콘 프리펩에는 반전색상으로 얇은 테두리를 만들어주어 분간이 갈수 있게 해주겠다

     

    조금은 더 나은것 같다. 완성본을 보고 더 테두리를 굵게 해야겠다 싶으면 그때 수정하겠다

Designed by Tistory.