Unity/하스스톤 유니티Clone By 고라니 TV

하스스톤 유니티Clone - #1 카드 정렬 (2)

noteasy_l.j.s 2022. 12. 27. 21:24
  • ScriptableObject
    • 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너.
    • 값의 사본이 생성되는 것을 방지하여 프로젝트의 메모리 사용을 줄일 수 있다.
  •  SortingGroup
    • Sprite Renderer의 렌더링 순서를 변경하는 컴포넌트. 
    • 낮은 순위의 Sorting Layer에 속한 정렬 그룹은 높은 순위의 Sorting Layer에 의해 겹쳐짐.
    • 같은 순위의 Sorting Layer에 속한 두 그룹의 오브젝트가 겹칠 수도 있으므로, Order In Layer 프로퍼티로 일괄된 우선 순위를 갖도록 할 수 있음.
    • 하스스톤 유니티Clone에서는 background < Characters < Card < Texts 의 구조를 가짐.(Sorting Layer)

 

1. 카드 데이터를 저장하는 컨테이너(ItemSO 만들기)

  • ScriptableObject를 정의하고, 메뉴에서 생성할 수 있도록 Script 작성
  • Card를 관리하는 CardManager Object에서 ItemSO를 이용해서 카드를 섞고, 생성.
// ItemSO.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]       // 클래스 또는 구조체의 정보를 Inspector에 노출
public class Item
{
    public string name; // 이름
    public int attack;  // 공격력
    public int health;  // 체력
    public Sprite sprite;   // Sprite
    public float percent;   // 카드에서 뽑힐 확률
}
[CreateAssetMenu(fileName = "ItemSO", menuName = "Scriptable Object/ItemSO")]   // ScriptableObject 의 인스턴스를 생성하는 메뉴 만들기.
public class ItemSO : ScriptableObject
{
    public Item[] items;        // Item 배열
}

Create -> Scriptable Object -> ItemSO 인스턴스를 생성.

 

Create -> Scriptable Object -> ItemSO 인스턴스를 생성.

 

카드 데이터 입력

 

2. 카드 꾸미기

카드 꾸미기

  • 카드는 Character, NameTMP, AttackTMP, HealthTMP 오브젝트들로 구성.
  • 각각의 구성요소들을 알맞은 위치로 이동시키고, Order 관련 Script를 적용.
    • 각 Renderer 간의 거리 차이를 정함.
    • 각 카드는 10씩의 간격을 가짐
    • 카드 객체 내부의 Renderer는 Character < NameTMP < AttackTMP < HealthTMP 순서로 거리가 멈. (1씩 증가)
    •  SortingLayer와 SortingOrder로 카드 간에 겹치는 일을 방지하거나, 카드 내에 각 Renderer(Sprite, Mesh)들끼리 겹치는 일을 방지.
    • TextMeshPRO는 Inspector에서 Order In Layer를 지정하지 못하니, Order.cs를 이용해서 Sorting Group을 설정. (현재 버전에서는 Extra Settings에서 지정 가능 한 듯)

Order In Layers만 이용
Sorting Group 이용

// Order.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Order : MonoBehaviour
{
    [SerializeField] Renderer[] backRenderers;          // 뒤쪽 렌더러
    [SerializeField] Renderer[] middleRenderers;        // 중앙 렌더러
    [SerializeField] string sortingLayerName;           // 레이어 이름
    int originOrder;

    public void Start()
    {
        //SetOrder(0);
    }

    public void SetOriginOrder(int originOrder)         // 카드가 맨 앞으로 올 필요가 있을 때
    {
        this.originOrder = originOrder;
        SetOrder(originOrder);
    }
    
    public void SetMostFrontOrder(bool isMostFront)		 // 나중에 카드가 확대 될 때 가장 맨 앞에 있어야 함.
    {
        SetOrder(isMostFront ? 100 : originOrder);
    }



    public void SetOrder(int order)
    {
        int mulOrder = order * 10;      // 카드와 카드 사이의 간격

        foreach (var renderer in backRenderers)
        {
            renderer.sortingLayerName = sortingLayerName;
            renderer.sortingOrder = mulOrder;
        }

        foreach (var renderer in middleRenderers)
        {
            renderer.sortingLayerName = sortingLayerName;
            renderer.sortingOrder = mulOrder + 1;           // backRenderers 보다 1 앞에 있게 둠.
        }
    }
}
3줄 요약
ScriptableObject는 Unity에서 대량의 데이터를 저장하는 컨테이너로 프로젝트의 메모리 사용을 줄일 수 있다.
2D 게임에서 배경, 캐릭터, 적, Text 등의 게임 요소들이 잘 보이는 것은 Sorting Group을 적절하게 해서 그러한 듯 하다.
Unity에서 대량의 데이터를 저장하는 컨테이너의 종류는 뭐가 더 있을까