2022년 7월 22일 금요일

Resharper 의 자동 리펙토링이 에러를 낼때

 JetBrain Resharper의 Quick Fix (자동 리펙토링)을 사용하면 갑자기 Files still read-only 라는 에러 메세지 팝업이 뜨거나, Fail to modify documents 라는 풍선도움말이 뜨고 리펙토링이 진행되지 않는 현상이 발생했다.

구글링 해보니 VisualStudio 의 소스제어 기능(git)이 파일 수정권한을 가져가서 그런듯.

메뉴->옵션->소스제어->플러그인 선택->현재 소스 제어 플러그 인 을 "Git" 에서 "없음"으로 바꾸면 됨


출처

2022년 1월 5일 수요일

언리얼 프로젝트 컴파일 시 메모리가 부족할 때

언리얼 엔진 프로젝트를 Visual Studio로 컴파일 하면 "Microsoft C-C++ Compiler Driver" 가 너무 많이 생성되어서 머신 메모리를 다 점유하여 머신이 거의 멈춰버리는 현상이 언제부터인가 발생했다.

구글링해서 찾은 해결법

https://forums.unrealengine.com/t/any-way-to-limit-the-number-of-microsoft-c-c-compiler-driver-cl-exe-instances-while-compile/211403

BuildConfiguration.xml 파일 위치는 EngineCode\Engine\Saved\UnrealBuildTool

2020년 7월 10일 금요일

TextMesh Pro의 italic 수치 조절하는 방법

유니티 포럼 링크



특정 텍스트만 조절할 수 없고 폰트 전체의 이텔릭 수치만 조절 가능.

 <i angle=30> 이렇게 Rich Text 도 된다고 하는데 이건 2019부터...

2020년 4월 30일 목요일

갑자기 Apple Sandbox 테스트가 안될때

가는 날이 장날이라고 빌드날 애플 결제 테스트가 실패하는 상황이 발생

안드로이드는 문제가 없고, iOS 기기에서 여러 번 앱을 껏다 키면서 IAP 테스트를 해 보니 상품 목록이 늦게 오거나 아이튠즈 샌드박스에 접속할 수 없다는 메세지가 출력되기도 함.

사내 모든 게임의 IAP 초기화가 실패.

애플의 System Status 페이지를 검색해서 들어가 보니 iTunes Sandbox에 Issue 있다고..


테스트 포기.

2020년 4월 13일 월요일

구글, 애플은 ₩, 원스토어는 ₩. 원 표시가 다르다.

원스토어 출시 준비를 하면서 기존 판매 상품들들 점검하고 있었는데 원스토어로 빌드했을 때 상품 가격의 원(₩) 표시가 출력되지 않았다. 로그를 출력했을때는 분명 문제 없었는데 실제 게임에서는 출력되지 않아서 더 큰 문제라고 생각했다.

상품 가격을 표시하기 위해 유니코드 상의 ISO 기반 통화 기호와 알파벳, 숫자들을 모아서 NotoSans 기반으로 폰트 아틀라스를 하나 만들고, TextMeshProUGUI 를 이용해 출력하고 있었는데, 혹시나 해서 원 표시의 유니코드를 출력해 보니 구글, 애플에서 가격을 받아올 때 쓰는 원 표시와 원스토어에서 받아오는 원 표시가 달랐다. 나무위키 참고

다행이라는 생각으로 전각 반각 원 표시를 다 추가해서 TextMeshPro 폰트롤 새로 만들었는데 NotoSans 폰트에는 U+FFE6 원 표시가 없었다.....(나눔고딕에는 있다)

급한대로 가격 string에서 U+FFE6를 U+20A9로 replace 해서 사용중이다.

2020년 2월 6일 목요일

mesh.vertices is too small. the supplied vertex array has less vertices than are referenced by the triangles array.

글자와 글자 사이에 스프라이트 폰트를 사용해야 할 일이 생겨 (ex. 상금 ⓒ 100)
TextMeshProUGui 에 sprite richText 를 사용하여 다음과 같이 설정하였다.

상금 <sprite="coin_gem" name="coin"> <color=#FFEA00>100</color>

다른 것은 수정하지 않고 텍스트 내용만 바꾸었을 뿐인데 

mesh.vertices is too small. the supplied vertex array has less vertices than are referenced by the triangles array.


해당 게임 오브젝트가 껏다 켜질 때마다 위의 에러가 콘솔창에 출력되었다. (다행히 글자 출력에는 문제가 없음)
구글링을 좀 해 보니 TextMeshPro의 MeshFilter를 Clear 하고 새로 new 해서 할당하라는 글이 있어서 따라 해 봤는데 수정되지 않아서 포기하는 심정으로 해당 게임 오브젝트만 지우고 새로 만들었더니 에러가 사라졌다.(?)
비슷하게 다른곳도 수정했는데 똑같은 에러가 나오고, 게임오브젝트를 지웠다 새로 만드니 역시 사라졌다.

결론 : 모르겠으면 지우고 새로 만들자

2020년 1월 17일 금요일

Unicode 공백문자 제거

닉네임 설정 시 공백문자를 제거하기 위한 코드
1 2 3 사이에 모든 유니코드 공백문자들이 들어있다.


1
2
3
string myString = "1   2          3";
myString = new string(myString.Where(c => !char.IsWhiteSpace(c)).ToArray());
Console.WriteLine(myString);
테스트 해 보니 123 으로 잘 나온다.

2020년 1월 6일 월요일

애용하는 c#, c++ Web IDE

간단한 테스트 로직 작성하고 싶은데 유니티 프로젝트에서 파일을 만들어서 테스트 런너를 돌리기 조차 귀찮을 때가 있다.
그럴때 유용한 사이트들 모음

https://dotnetfiddle.net/
https://rextester.com/

구름 도 나쁘지 않아서 꽤 사용했었다.

C++ 도 추가. C++ 17까지 지원한다.

2019년 12월 30일 월요일

Dictionary의 Key는 Mutable 해야 함

Dictionary의 Key로 long 이나 int 같은 기본 타입이 아닌 유저정의 Class 를 사용하는 경우, 해당 클래스가 Mutable 하지 않고 수정이 될때 문제가 발생한다.

Dictionary의 Key로 Class나 struct 가 사용될 때, Dictionary는 GetHashCode() 함수를 사용하게 되는데, 만약 Key로 사용하고 있는 Class의 인스턴스가 변경되는 경우 GetHashCode()의 결과도 바뀌게 되기 때문이다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public struct H
{
    public int a;
    public H(int _a)
    {
        a = _a;
    }
}

[Test]
public void HashCodeTest()
{
    var h = new H(0);
    Debug.Log($"HashCode = {h.GetHashCode()}");
    h.a = 100;
    Debug.Log($"HashCode = {h.GetHashCode()}");
    h.a = 1;
    Debug.Log($"HashCode = {h.GetHashCode()}");
}

위의 코드를 실행하면

HashCode = 498689296
HashCode = 498689396
HashCode = 498689297
의 결과가 출력된다.

EqualityComparer 를 사용할 것이 아니라면 수정될 만한 인스턴스는 Dictionary 의 Key로 사용하지 말자

C# Dictionary<> and mutable keys
 
 
 

2019년 12월 12일 목요일

Unity GPresto 변수 성능 테스트

GPresto에서 제공하는 메모리 변조 방지용 변수들을 사용해야 하는데 성능에 관한 의심이 들어 간단하게 테스트를 해 보았다.

bool 부터 Quaternion, Vector3 까지 지원해 주는데 제일 빈번하게 사용하는 int, float, Vector3만 테스트 했다.

각 타입에 최소 단위(1, 1.0f, Vector3.one)를 1억번 더한 결과, 다음과 같았다
(갤럭시s 8 기준)



int 형 : 8032 / 178 = 45.1배
float 형 : 38092 / 962 = 39.5배
Vector3형 : 54066 / 3808 = 14.2 배

결론 : 꼭 필요한 곳만 쓰자.

2019년 12월 3일 화요일

Android OBB 와 TextMeshPro

APK 가 150MB를 초과해서 OBB를 도입하고 있다.
기존 로그인 씬 보다 더 앞에 OBB다운로드 체크 씬을 도입하고 APK를 빌드해서 실행하니

위와 같은 에러를 뱉어내었다.

다운로드 확인을 위한 팝업에서 TextMeshPro를 사용 중이었는데, 타 팀에서도 TextMeshPro를 OBB체크 시에는 사용하지 않는다는 얘기를 들어 TextMeshPro 대신 일반 Text 로 교체하니 일단 에러는 사라졌다.

2019년 11월 27일 수요일

Jenkins에서 유니티로 실행한 Shell Script 가 끝나질 않는 문제 삽질 이야기


1. 우리팀 빌드머신은 iMac 이고 젠킨스로 빌드하고 있다.

2. 어셋 번들 파일 서버는 Amazon S3에 마련되어 있어 각 버전별로 폴더를 만들어서 업로드 하고 싶었다.

3. 버전이 클라이언트의 특정 변수에 설정되어 있어서 쉘크립트를 젠킨스가 직접 실행할수 없다. 서버 개발자 분께 부탁해서 버전을 파라메터로 받아서 S3의 버전 이름 폴더에 파일을 업로드 할 수 있는 스크립트를 만들었다.

4. 해당 스크립트를 어셋 번들 생성 후 유니티 코드로 호출 할 수 있도록 함수를 만들었다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static void RunQaBundleUploadScript()
    {
        Debug.Log($"업로드 스크립트 실행 준비");
        if (psi == null)
        {
            psi = new System.Diagnostics.ProcessStartInfo();
        }
        var v = new GlobalConfig.VersionInfo();
        string args =
            Path.Combine(Application.dataPath,
            $"Editor/QaBundleUploadScript/qa_{EditorUserBuildSettings.activeBuildTarget.ToString().ToLower()}_patch.sh {v.ClientVersionToString()}");

        psi.FileName = "/bin/sh";
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;
        psi.Arguments = args;
        psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized;
        psi.CreateNoWindow = true;
        var proc = System.Diagnostics.Process.Start(psi);
        proc.WaitForExit();//로그 출력을 위해
        var log = proc.StandardOutput.ReadToEnd();

        Debug.Log($"업로드 스크립트 실행 완료 {args}\n{log}");
    }

5. 단순 실행이 아니라 로그도 보고 싶어서 WaitForExit 와 ReadToEnd 를 사용하였다.
6. 유니티 에디터에서 해당 함수를 테스트 하고 동작이 확인되어 젠킨스 빌드를 돌렸는데 빌드도 되고 S3에 업로드도 잘 되었지만 젠킨스의 빌드 상태가 종료되지 않고 계속 대기상태가 유지되었다.
7. 서버 개발자분께서 알려 주셔서 WaitForExit 와 ReadToEnd 의 소스 코드를 다음과 같이 수정하니 젠킨스 빌드가 정상적으로 종료 되었다.


1
2
3
4
5
6
using(var proc = System.Diagnostics.Process.Start(psi))
{
    var log = proc.StandardOutput.ReadToEnd();
    proc.WaitForExit();
    Debug.Log($"업로드 스크립트 실행 완료 {DateTime.Now}\n{args}");
}

2019년 11월 25일 월요일

CJK UniCode Range

@"[\uFF21-\uFF3A]" // A-Z
@"[\uFF41-\uFF5A]"  // a-z
@"[\uFF10-\uFF19]"  // 0-9
@"[\uAC00-\uD7A3]"  // 가-힣
@"[\u1100-\u1112]"  // ㄱ-ㅎ
@"[\u3130-\u3163]"  // ㄱ-ㅎ(Compatible)ㅏ-ㅣ
@"[\u4E00-\u9FFF]" // Unified Hanja (Traditional/Simplify Chinese, Japanese, Korean)
@"[\u3040-\u30FC]" // Japanese

출처

한글
 구분 시작 끝
 한글(자음, 모음) 1100 11FF
 호환용 한글(자음, 모음) 3131 318F
 한글 음절(가~힣) AC00 D7A3

한자
 구분 시작 끝
 한중일 부수 보충 2E80 2EFF
 한중일 통합 한자 확장 - A 3400 4DBF
 한중일 통합 한자 4E00 9FBF
 한중일 호환용 한자 F900 FAFF
 한중일 통합 한자 확장 20000 2A6DF
 한중일 호환용 한자 보충 2F800 2FA1F

일어
 구분 시작 끝
 하라가나 3040 309F
 가타카나 30A0 30FF
 가타카나 음성 확장 31F0 31FF

[출처] 유니코드 한글, 한자, 일어 범위|작성자 realization

2019년 5월 22일 수요일

Max Size 가 원래 크기보다 작은 스프라이트의 SetNativeSize 하기

256x256 사이즈의 스프라이트를 128로 Max Size를 줄여서 사용할 때 SetNativeSize 를 하면 128x128 이 아니라 256x256 의 원래 크기로 돌아가 버린다

그럴 땐 overrideSprite의 사이즈를 이용하면 된다.

Sprite overrideSprite = GetComponent<Image>().overrideSprite;
icon.rectTransform.sizeDelta = new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);

2019년 3월 22일 금요일

TextMeshPro의 글자 가로 세로 길이

TextMeshProUGUI 의 Text 글자들의 가로 세로 길이 구하는 법

GetPreferredValues()

Function to Calculate the Preferred Width and Height of the text object.
Declaration
public Vector2 GetPreferredValues()
Returns

TypeDescription
Vector2