반응형

 

 

 

 

에러 현상

- 스킨정보가 있는 SkeletonDataAsset을 교체한 뒤, 스킨 설정 방법에 따라 Material 정보가 없어지는 현상이 있다.

- Skeleton 정보는 정상적으로 적용되고 텍스쳐만 없는 상태로 보여진다.

- 해당 현상은 SkeletonAnimation 컴포넌트에서만 일어나며, SkeletonGraphic 컴포넌트에서는 이상이 없다.

 

 

 

코드

using Spine.Unity;

SkeletonAnimationClass.skeletonDataAsset = SomeSkeletonDataAsset;
SkeletonAnimationClass.Initialize(true);

//필드 값을 변경하면 MeshRenderer의 Material이 로드되지 않음.
SkeletonAnimationClass.initialSkinName = "skin name";
//SetSkin(str) 함수로 스킨을 변경하면 Material이 정상적으로 로드 됨.
SkeletonAnimationClass.skeleton.SetSkin("skin name";);
  • SkeletonGraphic 컴포넌트는 InitialSkinName 필드값을 변경해도 정상적으로 작동한다.

 

 

 

 

 

반응형
반응형

 

 

 

 

FindObjectsOfType<T>()

- 해당 함수로 구해지는 배열 원소들은 하이어라키 배치대로 순서가 보장되지 않는다.

- 즉, 다음과 같이 보여진다.

 

 

 

 

해결 방법

- 위 문제를 해결하기위해서는 2가지 방법이 있다.

  1. 인스펙터에서 직접 드래그 앤 드롭 해준다.

  2. FindObjectsOfType<T>로 배열을 구한 뒤, 정렬을 한다.

- 1번과 같은 경우는 노가다가 심해진다. 따라서, 코드로 정렬을 해주는 방법을 취한다.

- 이 때, 배열의 정렬은 transform.GetSiblingIndex() 값을 비교해서 정렬을 해주면 된다.

- SiblingIndex 값은 하이어라키에 배치된 순서의 값을 반환해준다.

 

 

 

코드

using System;
using UnityEngine;

SomeClass[] arr = FindObjectsOfType<SomeClass>();
Array.Sort(arr, (a, b) =>
{
    return a.transform.GetSiblingIndex().CompareTo(b.transform.GetSiblingIndex());
});
  • 위 코드는 오름차순으로 정렬되기 때문에 내림차순으로 정렬하고 싶으면 return 라인에 a와 b의 위치를 변경하면 된다.

 

 

 

결과

 

 

 

 

 

반응형
반응형

 

 

 

 

제네릭 싱글톤(Generic singleton)

- 싱글톤 : 객체의 인스턴스가 오직 하나인 디자인 패턴

- Generic class : 데이터 형식을 일반화한 클래스를 말한다.

 

 

코드

using UnityEngine;

public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    [SerializeField]
    private bool dontDestroy = true;
    private static T instance = null;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = InitManager<T>();
            }
            return instance;
        }
    }

    protected static U InitManager<U>() where U : MonoBehaviour
    {
        GameObject go = null;
        U obj = FindObjectOfType<U>();
        if (obj == null)
        {
            go = new GameObject(typeof(U).Name);
            go.AddComponent<U>();
        }
        else
        {
            go = obj.gameObject;
        }

        DontDestroyOnLoad(go);
        return go.GetComponent<U>();
    }

    private void Awake()
    {
        if (instance == null)
        {
            if (dontDestroy)
            {
                Instance.Init();
            }
            else
            {
                instance = GetComponent<T>();
                Init();
            }
        }
        else
        {
            Destroy(gameObject);
        }
    }

    protected abstract void Init();
}
  • DontDestroyOnLoad를 사용하지 않으려면 인스펙터 창에서 해당 bool값을 false로 변경해준다.
  • Init 함수를 추상 함수로 지정해서 싱글톤으로 지정할 클래스의 초기화를 Init에서 하도록 유도한다.

 

 

 

 

반응형
반응형

 

 

 

※ isometric 타일맵을 기준으로 작성된 포스팅입니다.

 

타일맵 컴포넌트에서 타일을 그리면 그려진 타일의 배열의 크기를 가져올 수 있다. isometric 기준으로 타일맵의 배열은 다음과 같이 구성된다.

 

 

주의할 점이 있는데 타일맵 자체에서 배열을 제공하는것이 아니라 타일맵이 그려진 사이즈(Vector2) 값을 가지고있는것이기 때문에 타일맵의 사이즈 값과 타일맵의 셀 바운드값을 가져와서 직접 배열을 초기화해줘야한다.

이 때, 셀 바운드값은 최하단 타일을 기준으로 값이 정해지기 때문에 이 값이 무조건 0에서부터 시작하지 않는다.

 

 

  • 타일맵 초기화 코드
private void InitTileArray()
{
    Tilemap tilemap = GetComponent<Tilemap>();
    Vector2[,] tileArray = new Vector2[m_cTilemap.size.y, m_cTilemap.size.x];
    
    Vector3Int tilePos;
    for (int y = tilemap.cellBounds.yMin; y < tilemap.cellBounds.yMax; y++)
    {
        for (int x = tilemap.cellBounds.xMin; x < tilemap.cellBounds.xMax; x++)
        {
            tilePos = new Vector3Int(x, y, 0);
            if (tilemap.HasTile(tilePos))
            {
                int arrX = x - tilemap.cellBounds.xMin;
                int arrY = y - tilemap.cellBounds.yMin;
                Vector3 tileWorldPos = tilemap.CellToWorld(tilePos);
                tileArray[arrY, arrX] = tileWorldPos;
            }
        }
    }
}

  ※ tileWorldPos의 값은 타일의 중앙좌표가 아닌 하단 모서리의 좌표이기 때문에, 중앙좌표를 위한 추가값을 넣어줘야한다.

 

 

 

 

  • 추가 주의사항

- 특정 위치에 타일맵을 한번 그리게되면 그 위치의 타일맵을 지운다고해도 그 위치는 바운드값에 포함이 된다. 그렇기때문에 타일맵 컴포넌트에서 옵션(…)을 눌러서 'Compress Tilemap Bounds'를 눌러주거나 코드에 CompressBounds()를 호출해준다.

 

 

 

 

반응형
반응형

 

2018 LTS에서 2019 LTS로 넘어오면서 이상한게 눈에 띄었다.

위와 같이 한글로 주석해놓은게 유니티 인스펙터 창에서 미리보기할 때 깨져서 보이는것이었다.

간단하게 작업할때는 그냥 무시하고 사용했는데, 깃허브에 올리고 맥에서도 사용하려하니 장애가 많아서 결국 해결을 해야했다.

 

원인은 뻔했다. 파일이 UTF-8로 저장되어있지 않은것..

저장할 때마다 UTF-8로 변경해서 저장하면 되긴 한데, 매번 스크립트 생성할때마다 신경쓰기는 너무나 귀찮다.

해결법을 찾아보던 중, 스크립트 템플릿이 있는데 그 파일을 UTF-8로 변경해두변 된다고해서 해봤는데 어림없었다..

그 뒤, EditorConfig라는것을 찾아서 해결을 했다. 지금부터 설정법을 알아보자.

 

 

 

 

1. 기존 스크립트 변경법

- 이 부분은 노가다하는 수밖에 없다.

 

1-1) 스크립트를 연 뒤, 파일다른 이름으로 저장으로 저장을 시도한다.

1-2) 저장 옆에 화살표를 눌러 인코딩하여 저장을 선택한다.

1-3) 고급 저장 옵션창에서 인코딩란을 다음과 같이 설정한 다음 확인을 눌러 저장한다.

 

 

 

 

2. EditorConfig로 인코딩 설정하기

- EditorConfig : 프로젝트의 구성 파일 형식, 코딩 스타일을 정의하는 텍스트 편집기 플러그인(이라고 한다.)

 

2-1) 프로젝트안에 파일을 생성한 뒤, .editorconfig로 파일명을 설정해준다.

2-2) 생성한 파일을 메모장이나 VS로 연 뒤, 다음과 같이 작성해준다.

root = true

[*]
charset = utf-8

2-3) 저장을 하게되면 이후에 생성되는 스크립트는 UTF-8 인코딩으로 자동으로 설정된다.

 

※ 추가 설정법은 다음 사이트 참고

 

EditorConfig

What is EditorConfig? EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection o

editorconfig.org

 

 

 

결과)

 

반응형

+ Recent posts