ShovelingLife
A Game Programmer
ShovelingLife
전체 방문자
오늘
어제
  • 분류 전체보기 (1074)
    • 그래픽스 (57)
      • 공통 (19)
      • 수학 물리 (22)
      • OpenGL & Vulkan (1)
      • DirectX (14)
    • 게임엔진 (183)
      • Unreal (69)
      • Unity (103)
      • Cocos2D-X (3)
      • 개인 플젝 (8)
    • 코딩테스트 (221)
      • 공통 (7)
      • 프로그래머스 (22)
      • 백준 (162)
      • LeetCode (19)
      • HackerRank (2)
      • 코딩테스트 알고리즘 (8)
    • CS (235)
      • 공통 (21)
      • 네트워크 (44)
      • OS & 하드웨어 (55)
      • 자료구조 & 알고리즘 (98)
      • 디자인패턴 (6)
      • UML (4)
      • 데이터베이스 (7)
    • 프로그래밍 언어 (349)
      • C++ (168)
      • C# (90)
      • Java (9)
      • Python (33)
      • SQL (30)
      • JavaScript (8)
      • React (7)
    • 그 외 (10)
      • Math (5)
      • 일상 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Source Code 좌측 상단에 복사 버튼 추가 완료
  • 언리얼 엔진 C++ 빌드시간 단축 꿀팁
  • 게임 업계 코딩테스트 관련
  • 1인칭 시점으로 써내려가는 글들

인기 글

태그

  • 그래픽스
  • 알고리즘
  • 포인터
  • Unity
  • 티스토리챌린지
  • 배열
  • 문자열
  • 클래스
  • 파이썬
  • 유니티
  • 언리얼
  • 백준
  • 오블완
  • C++
  • C
  • string
  • 프로그래머스
  • SQL
  • c#
  • 함수

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ShovelingLife

A Game Programmer

[Unity] UI - 마인크래프트 형태 조합창
게임엔진/개인 플젝

[Unity] UI - 마인크래프트 형태 조합창

2024. 11. 9. 17:06

세팅

public class Minecraft_inventory_setup : MonoBehaviour
{
    // 슬롯 오브젝트 담음
    List<Slot> m_inventory_slot_list = new List<Slot>();


    [ContextMenu("UI 인벤토리창 생성")]
    public void Create_crafting_set()
    {
        // 클리어 후 슬롯 생성
        m_inventory_slot_list.Clear();

        for (int i = 0; i < 27; i++)
        {
            // 슬롯 오브젝트 세팅
            GameObject tmp_obj = Instantiate(Crafting_UI_manager.instance.slot_obj, Crafting_UI_manager.instance.Get_parent_obj(1));
            tmp_obj.name = string.Format("Inventory_slot_{0}", i+1);

            // 슬롯 오브젝트 자식 세팅
            tmp_obj.transform.GetChild(0).name = string.Format("Inventory_child_slot_{0}", i + 1);
            m_inventory_slot_list.Add(tmp_obj.transform.GetChild(0).GetComponent<Slot>());
        }
    }

    [ContextMenu("UI 인벤토리창 삭제")]
    public void Delete_crafting_set()
    {
#if UNITY_EDITOR
        // 삭제 후 클리어
        for (int i = 0; i < m_inventory_slot_list.Count; i++)
             DestroyImmediate(m_inventory_slot_list[i]);

        m_inventory_slot_list.Clear();
#endif
    }
}

slot 클래스

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;


[RequireComponent(typeof(Image))]
[RequireComponent(typeof(Collider2D))]
[RequireComponent(typeof(Rigidbody2D))]
public class Slot : MonoBehaviour
{
    public Image current_image;
    public Text quantity_txt;
    int m_current_quantity = 0;
    public bool is_test;
    string m_current_obj_id;
    string m_current_obj_type_id;

    public string current_obj_id_prop
    {
        get => m_current_obj_id;
    }

    public string current_obj_type_id_prop
    {
        get => m_current_obj_type_id;
    }

    public int current_quantity_prop
    {
        get => m_current_quantity;
        set => m_current_quantity = value;
    }


    private void Start()
    {
        if (is_test)
            current_quantity_prop = 10;

        Init_values();
    }

    void Update()
    {
        Show_ui();
        //Item_id_update();

        try
        {
            if (Crafting_UI_manager.instance != null)
                Item_id_update();
        }
        catch
        {
        }

        try
        {
            if (Equipment_UI_manager.instance != null)
                Update_item_type_id();
        }
        catch
        {
        }


        //if (current_image.sprite != null)
        //{
        //}
    }

    // 값 초기화
    protected void Init_values()
    {
        current_image = GetComponent<Image>();
        current_image.color = (current_image.sprite == null) ? Global.sprite_fade_color : Global.original_color;
    }

    // 값 다시 세팅
    public void Reset()
    {
        current_image.sprite = null;
        quantity_txt.text = "";
        m_current_quantity = 0;
    }

    // 현재 갯수를 보여줌
    public void Show_ui()
    {
        if (m_current_quantity == 0)
        {
            current_image.color = Global.sprite_fade_color;
            current_image.sprite = null;
            quantity_txt.text = null;
        }
        else
        {
            current_image.color = Global.original_color;
            quantity_txt.text = m_current_quantity.ToString();
        }
    }

    // 아이디 업데이트 < 조합창
    void Item_id_update()
    {
        if (current_image == null)
            return;

        if (current_image.sprite == null)
        {
            m_current_obj_id = "0";
            return;
        }

        string current_image_name = current_image.sprite?.name;

        // try - catch로 인해 불가
        //if (string.IsNullOrEmpty(current_image_name))
        //{
        //    m_current_obj_id = "0";

        //    return;
        //}

        // 약자
        // w = wood
        // sw= spider web
        // g = gold
        // fr = fishing rod

        // EX, not final
        switch (current_image_name)
        {
            case "spritesheet_107": // 기본 나무

                m_current_obj_id = "w1";
                break;

            case "spritesheet_109": // 기본 나무 막대 

                m_current_obj_id = "w2";
                break;

            case "spritesheet_187": // 거미줄

                m_current_obj_id = "sw1";
                break;

            case "spritesheet_113": // 금 소형 덩어리

                m_current_obj_id = "g1";
                break;

            case "spritesheet_205": // 기본 낚싯대

                m_current_obj_id = "fr1";
                break;
        }
    }
}

조합 매니저 클래스

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class Crafting_UI_manager : Singleton_local<Crafting_UI_manager>, IPointerEnterHandler, IPointerClickHandler
{
    Cursor_slot slot_cursor;
    // 아이콘 오브젝트
    public GameObject item_selected_obj;
    // 아이템 이동 패널
    //public Transform move_panel_trans;
    // 슬롯 오브젝트
    public GameObject slot_obj;

    // 제조 부모 오브젝트
    public Transform crafting_obj_parent;
    // 인벤토리 부모 오브젝트
    public Transform inventory_obj_parent;

    // ------- 슬롯 관련 -------

    // 슬롯 집합체
    public Crafting_setup crafting_setup;
    public Minecraft_inventory_setup inventory_setup;

    // 결과 슬롯 및 커서 슬롯
    Slot m_slot;
    public Crafting_result_slot crafting_result_slot;

    // 레시피 관련
    Crafting_recipee crafting_recipee;
    string m_current_item_id;
    public string current_item_id_prop
    {
        set { m_current_item_id = value; }
    }


    private void Start()
    {
        Init_values();
    }

    private void Update()
    {
        slot_cursor.gameObject.transform.localPosition = Input.mousePosition;
        //Debug.Log(m_current_item_id);
    }    

    public void OnPointerClick(PointerEventData eventData)
    {
        List<RaycastResult> ray_result_list = new List<RaycastResult>();
        eventData.position = Input.mousePosition;

        //Debug.LogFormat($"클릭 위치: {Camera.main.ScreenToWorldPoint(Input.mousePosition)}");
        // 왼쪽 클릭, 아이템 이동
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            EventSystem.current.RaycastAll(eventData, ray_result_list);

            foreach (var item in ray_result_list)
            {
                m_slot = item.gameObject.GetComponent<Slot>();

                // 슬롯 정보를 가져왔을 시
                if (m_slot != null)
                {
                    if (m_slot == crafting_result_slot) // 현재 선택된 아이템이 없을 때만 교체
                    {
                        if (slot_cursor.current_image.sprite == null)
                        {
                            Get_crafted_item();
                            Swap();
                        }
                        return;
                    }
                    Sprite first_sprite = slot_cursor.current_image.sprite;
                    Sprite second_sprite = m_slot.current_image.sprite;

                    if (first_sprite == second_sprite) // 같으면 융합
                    {
                        crafting_result_slot.current_quantity_prop = 0;
                        Fuse();
                    }
                    else // 틀리면 교체
                        Swap();
                }
            }
        }
        // 오른쪽 클릭 아이템 놔둠
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            Debug.Log("CLICKED UI 오른쪽");
            EventSystem.current.RaycastAll(eventData, ray_result_list);

            foreach (var item in ray_result_list)
            {
                m_slot = item.gameObject.GetComponent<Slot>();

                if (m_slot != null)
                    Set_one_item();
            }            
        }
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        List<RaycastResult> ray_result_list = new List<RaycastResult>();
        EventSystem.current.RaycastAll(eventData, ray_result_list);

        foreach (var item in ray_result_list)
        {
            Debug.Log(item.gameObject.name);
            Slot tmp_slot = item.gameObject.GetComponent<Slot>();

            // 슬롯 정보를 가져왔을 시
            if (tmp_slot != null)
            {
                item_selected_obj.transform.SetParent(tmp_slot.transform.parent);
                item_selected_obj.transform.localPosition = tmp_slot.transform.localPosition;
            }
        }
    }

    // 초기화
    void Init_values()
    {
        slot_cursor = FindObjectOfType<Cursor_slot>();
        crafting_result_slot = FindObjectOfType<Crafting_result_slot>();
        crafting_recipee = FindObjectOfType<Crafting_recipee>();
        crafting_setup = FindObjectOfType<Crafting_setup>();
        inventory_setup = FindObjectOfType<Minecraft_inventory_setup>();
    }

    // 부모 오브젝트를 반환
    public Transform Get_parent_obj(int _index)
    {
        Transform tmp_transform = null;

        switch (_index)
        {
            case 0:
                tmp_transform = crafting_obj_parent;
                break;

            case 1:
                tmp_transform = inventory_obj_parent;
                break;
        }
        return tmp_transform;
    }

    // 교체
    void Swap()
    {
        Debug.Log("교체");
        Sprite tmp_sprite = slot_cursor.current_image.sprite;
        int tmp_value = slot_cursor.current_quantity_prop;
        slot_cursor.current_image.sprite = m_slot.current_image.sprite;
        slot_cursor.current_quantity_prop = m_slot.current_quantity_prop;
        m_slot.GetComponent<Image>().sprite = tmp_sprite;
        m_slot.current_quantity_prop = tmp_value;
        crafting_result_slot.current_quantity_prop = 0;
    }

    // 융합
    void Fuse()
    {
        Debug.Log("융합");
        slot_cursor.current_quantity_prop += m_slot.current_quantity_prop;
        m_slot.current_quantity_prop=0;
        m_slot.current_image.sprite = null;
    }

    // 아이템 한개만 설정
    void Set_one_item()
    {
        // 예외 처리
        if (slot_cursor.current_image.sprite != m_slot.current_image.sprite)
        {
            if (m_slot.current_image.sprite!=null)
                return;
        }            
        slot_cursor.current_quantity_prop--;
        m_slot.current_quantity_prop++;
        m_slot.current_image.sprite = slot_cursor.current_image.sprite;

        if (slot_cursor.current_quantity_prop == 0)
            slot_cursor.current_image.sprite = null;
    }

    // 아이템 가져오기
    public void Get_crafted_item()
    {
        if (m_current_item_id == null)
            return;

        string[] final_item_arr = m_current_item_id.Split(',');

        for (int i = 0; i < final_item_arr.Length-1; i++)
        {
            if (final_item_arr[i]!="0") // 삭제
                crafting_setup.crafting_slot_list[i].current_quantity_prop = 0;
        }
        Crafting_recipee.instance.is_made = false;
    }

    // 현재 매칭되는 아이템 갯수 가져오기
    public int Get_crafted_item_quantity()
    {
        string[] final_item_arr = m_current_item_id.Split(',');
        int sum = 0;

        for (int i = 0; i < final_item_arr.Length - 1; i++)
        {
            if (final_item_arr[i] != "0") // 합산
                sum += crafting_setup.crafting_slot_list[i].current_quantity_prop;
        }
        return sum;
    }
}

//Vector3 mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//RaycastHit hit;
//Physics.Raycast(ray,out hit, Mathf.Infinity, Global.Get_raycast_layermask_index("Slot"));\

// 교체 시작 부모 및 위치
//void Swap()
//{
//    Debug.Log("교체");
//    Slot_info tmp_slot_info = new Slot_info();
//    tmp_slot_info = m_first_slot;
//    m_first_slot.slot.transform.SetParent(m_last_slot.parent);
//    m_first_slot.slot.transform.localPosition = m_last_slot.current_pos;
//    m_last_slot.slot.transform.SetParent(tmp_slot_info.parent);
//    m_last_slot.slot.transform.localPosition = tmp_slot_info.current_pos;
//    m_click_count = 0;
//}

조합 레시피

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

[System.Serializable]
public class Crafting_recipee_data
{
    public Global_recipe_data[] arr;
}

public class Crafting_recipee : MonoBehaviour
{
    // 싱글톤
    static Crafting_recipee        m_instance;
    public static Crafting_recipee instance
    {
        get { return m_instance; }
    }
    public Dictionary<string, Global_recipe_data> current_items_data_dic = new Dictionary<string, Global_recipe_data>();
    // 전체 sprite 업로드
    //[SerializeField] Sprite[] all_item_sprites_arr;
    [Header("현재 제조 아이템 데이터")] 
    public Crafting_recipee_data global_recipe_data;

    // 최종 슬롯 관련
    Sprite               m_tmp_sprite;
    Crafting_result_slot m_tmp_slot;
    Crafting_setup       m_tmp_setup;
    const int k_total_crafting_slot_count = 9;

    [SerializeField]
    string m_tmp_item_id = null;
    string m_current_item_id=null;
    string m_last_item_id = null;
    public string current_item_id_prop
    {
        get { return m_current_item_id; }
    }

    int m_current_item_quantity = 0;
    public int current_item_quantity_prop
    {
        get { return m_current_item_quantity; }
    }
    int m_quantity_needed_to_craft = 0;
    public bool is_made = false;


    private void Awake()
    {
        if (m_instance == null)
            m_instance = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        Init_values();
    }

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

    // 값 초기화
    void Init_values()
    {
        m_tmp_slot = Crafting_UI_manager.instance.crafting_result_slot;
        m_tmp_setup = Crafting_UI_manager.instance.crafting_setup;
        
        var arr = global_recipe_data.arr;

        for (int i = 0; i < arr.Length; i++)
             current_items_data_dic.Add(arr[i].item_id, arr[i]);
    }

    // 제조창 감시
    void Check_crafting_slot()
    {
        for (int i = 0; i < k_total_crafting_slot_count; i++)
        {
            var craftingSlotProp = m_tmp_setup.crafting_slot_list[i].current_obj_id_prop;
            m_current_item_id += craftingSlotProp;
            m_tmp_item_id += craftingSlotProp + ",";
        }
    }

    // 최종 슬롯 업데이트 [아이템 아이디 바탕으로]
    void Update_current_slot()
    {
        if (!is_made) // 아이템이 제작 되었으면
        {
            m_tmp_slot.current_quantity_prop = 0;

            for (int i = 0; i < global_recipe_data.arr.Length; i++)
            {
                if (m_current_item_id == global_recipe_data.arr[i].item_id)
                {
                    var curItem = current_items_data_dic[m_current_item_id];
                    m_tmp_sprite = curItem.item_sprite;
                    m_current_item_quantity = curItem.item_quantity;
                    m_quantity_needed_to_craft = curItem.item_craft_count;
                    Crafting_UI_manager.instance.current_item_id_prop = m_tmp_item_id;
                    m_last_item_id = m_current_item_id;
                    is_made = true;
                }
            }
        }
        else
        {
            if (m_current_item_id != m_last_item_id) // 다른 아이템을 올렸을 시
            {
                is_made = false;
                m_tmp_slot.current_quantity_prop = 0;
            }
            else
            {
                int sum = Crafting_UI_manager.instance.Get_crafted_item_quantity();
                m_tmp_slot.current_image.sprite = m_tmp_sprite;
                m_tmp_slot.current_quantity_prop = m_current_item_quantity * (sum / m_quantity_needed_to_craft);
            }
        }
        m_current_item_id = null;
        m_tmp_item_id = null;
    }
}

 

빈 칸은 0 나머지는 아이디를 따라감

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

[CreateAssetMenu(fileName = "Global_recipe_data", menuName = "Create_scriptable_global_recipe_data/global_recipe_data", order = 0)]
public class Global_recipe_data : ScriptableObject
{
    public Sprite item_sprite;
    public string item_id;
    public int    item_quantity;
    public int    item_craft_count;

    //[EX_ITEM_ID]
    //[0] 1	 [3] 4]	 [6] 7]
    //[1] 2	 [4] 5]	 [7] 8]
    //[2] 3	 [5] 6]	 [8] 9]
}

조합 장면

 

 

 

저작자표시 (새창열림)

'게임엔진 > 개인 플젝' 카테고리의 다른 글

[Unity] UI - 로그인 및 채팅 시스템  (0) 2024.11.09
[Outdated] 농장 시뮬레이터 개인작  (0) 2024.04.30
플레이어 방향에 따른 발사 위치 변경  (0) 2024.04.23
Flow Free 3 - UI  (0) 2024.03.27
Flow Free 2 - 슬롯(그리드)과 파이프(연결선)  (0) 2024.03.27
    '게임엔진/개인 플젝' 카테고리의 다른 글
    • [Unity] UI - 로그인 및 채팅 시스템
    • [Outdated] 농장 시뮬레이터 개인작
    • 플레이어 방향에 따른 발사 위치 변경
    • Flow Free 3 - UI
    ShovelingLife
    ShovelingLife
    Main skill stack => Unity C# / Unreal C++ Studying Front / BackEnd, Java Python

    티스토리툴바