반응형

 

 

 

 

제네릭 싱글톤(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

 

 

 

결과)

 

반응형
반응형

 

※ 해당 포스팅은 유니티 물리, 힌지 조인트를 사용하는것이 아닌 단순히 진자 운동을 보이게 하기위한 포스팅이다.

 

삼각함수를 이용하여 진자운동을 구현해볼것이다.

최종 목표는 진자운동을 구현하여 좌우로 흔들리는 철퇴 장애물을 만드는것.

 

구현하기에 앞서 삼각함수 그래프를 먼저 살펴본다.

파란선이 sin 그래프, 빨간선이 cos 그래프이다. (그림이 조악한건 이해바람..)

위 두 그래프는 1과 -1을 반복하기 떄문에 우리는 이 특성을 이용하여 진자 운동을 구현할 것이다.

진자 운동 코드를 만들기 전에 삼각함수 그래프를 이용한 움직임이 어떤지 확인해보기 위해 위, 아래로 먼저 표현을 해보자.

 

 

 

사용 예시

이번 예시에서는 Vector3.Lerp()의 마지막 인자 t의 값을 Mathf.Sin()으로 구해서 구체의 Position값을 변경하는 형태이다.

참고로 Vector3.Lerp()t인자 값은 0~1로 넣어줘야하는데 Mathf.Sin()의 값은 -1~1이다. 그렇기 때문에 약간의 추가 작업이 필요하다. t인자 값을 구하기 위한 코드는 다음과 같다.

float lerpTime += Time.deltaTime;
(Mathf.Sin(lerpTime) + 1) * 0.5f; //Lerp()의 t인자 값

그럼 본격적으로 철퇴 장애물을 만들어보자.

 

 

 

유니티 게임오브젝트 세팅

1. 빈 게임오브젝트를 만들어준다.

  ※ 이 게임오브젝트가 최상위 부모 오브젝트이다.

2. 빈 게임오브젝트의 자식으로 체인 오브젝트를 만들어준 뒤 체인 오브젝트의 위쪽을 부모 오브젝트의 중심에 맞춰준다.

3. 체인 오브젝트의 자식으로 철퇴 오브젝트를 만들어준다.

 

이것으로 게임오브젝트 세팅이 완료되었다. 설명이 따로 필요없을정도로 간단하다.

이제 최상위 부모 오브젝트를 좌우로 회전시켜주기만 하면 진자운동을 하는 철퇴 장애물을 만들 수 있는것이다!

회전 시켜줄 게임 오브젝트에 연결해줄 코드를 살펴보자

 

 

 

코드

using UnityEngine;

public class Pendulum : MonoBehaviour
{
    public float angle = 0;
    
    private float lerpTime = 0;
    private float speed = 2f;
    
    private void Update()
    {
        lerpTime += Time.deltaTime * speed;
        transform.rotation = CalculateMovementOfPendulum();
    }
	
    Quaternion CalculateMovementOfPendulum()
    {
        return Quaternion.Lerp(Quaternion.Euler(Vector3.forward * angle), 
        	Quaternion.Euler(Vector3.back * angle), GetLerpTParam());
    }
	
    float GetLerpTParam()
    {
        return (Mathf.Sin(lerpTime) + 1) * 0.5f;
    }
}

  ※ angle값은 public으로 선언했으므로, 인스펙터 창에서 입맛대로 바꿔주면 된다.

  ※ 예시에서는 Mathf.Sin()을 사용했지만, Mathf.Cos()도 사용 가능하다. 포스팅 상단의 그림에서 봤듯이 Lerp()의 t인자값을 0.5(Sin)부터 시작할 것이냐 1(Cos)부터 시작할 것이냐의 차이다.

 

 

 

결과

 

반응형
반응형

※ 해당 에러가나는 유니티 버전은 Hub에서 유니티 설치시, JDK를 같이 설치하는 버전부터이다.


구글 플레이 게임 서비스(이하 GPGS)를 연동하기위해 플러그인을 다운받아 유니티에 임포트를 하고 Resolve를 했는데, 난데없는 에러가 떴다.

 

Gradle failed to fetch dependencies.
ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

 

'JAVA_HOME'이라는게 설정되지 않았다고한다.

찾아보니 최근 유니티들은 Hub에서 유니티 설치시, SDK, NDK, JDK를 다 설치하다보니 JAVA를 따로 설치할 필요가 없다. 문제는 여기서 발생하는데 GPGS 플러그인 설치 후, Resolve를 할 때 에러가 발생하는것이다.

에러를 추가로 읽어보면,

 

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.

 

JAVA가 설치된 곳을 JAVA_HOME 변수와 일치시켜달라고 한다. 즉, JAVA_HOME이라는 환경변수를 설정해주면 된다.

그럼 시작해보자!

 

환경변수 설정

1. 내 컴퓨터에서 속성에 들어간다.

2. 고급 시스템설정 - 환경변수 버튼을 눌러준다.

 

3. 시스템 변수 - 새로 만들기 버튼을 눌러 다음과 같이 설정한다.

4. 변수 값에 OpenJDK의 경로를 넘겨준다

  ※ 경로 : 유니티 설치 경로\Editor\Data\PlaybackEngines\AndroidPlayer\OpenJDK

 

 

여기까지 설정을 마쳤다면 이제 재부팅 후 다시 Resolve를 시도해보자!

그러면 Resolve가 진행되며 위와같이 정상적으로 성공 메세지를 받을 수 있다!

 

반응형

+ Recent posts