스프라이트 애니메이션을 개발하며

유니티 애니메이션 클립 미리보기같은 느낌으로
에디터에서 애니메이션을 미리보는 기능을 만들었다

 

개발하다보니 문제가 생겼는데

에디터의 OnInspectorGUI나 OnPreviewGUI 같은 함수는
"마우스가 인스펙터 위로 지나갈 때"만 다시 그려진다는 것

https://docs.unity3d.com/ScriptReference/Editor.RequiresConstantRepaint.html

요 함수를 오버라이드해 주기적으로 Repaint를 요청할 수 있다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using UnityEditor;
 
[CustomEditor(typeof(AnimationData), true)]
public class AnimationDataEditor : Editor
{
    private double lastTime;
 
 
    public override bool RequiresConstantRepaint() => true;
 
    public override void OnInspectorGUI()
    {
        // EditorApplication.timeSinceStartup 을 사용해 에디터에서 시간 측정을 할 수 있다
        var currentTime = (float) (EditorApplication.timeSinceStartup - lastTime); 
 
        ...
    }
}
cs

 

블로그 이미지

stuban

ㅇ.ㅇ

,

 

유니티 패키지 매니저를 통해 Newtonsoft Json을 설치할 수 있지만
패키지 목록에서는 찾을 수 없고 
무조건 Add package by name 을 통해 추가해야 한다

(프로젝트 세팅의 enable pre-release packages 옵션과 관련 없음)

com.unity.nuget.newtonsoft-json

 

 

 

유니티 내장 json 툴을 사용하는 것을 권장하고
굳이 newtonsoft json쓸거면 패키지를 통해 설치하라고 한다

근데 왜 패키지 매니저 목록에 안나오게 하고
프로젝트 버전 바꿀때 마다 추가했던 패키지가 사라지는데???

https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.2/manual/index.html

블로그 이미지

stuban

ㅇ.ㅇ

,

[프로그래밍/유니티] - 유니티 좌표에 따른 정렬 기준 바꾸기

기존에는 Edit->Project Setting->Graphics->Transparency Sort ModeCoustom Axis로 설정해
좌표에 따른 소팅 오더를 쉽게 세팅할 수 있었다

 

그런데 최근 URP로 전환하며 기존에 CoustomAxis를 설정하는 필드가 사라져버렸다

정확히는 숨어버린 것인데

프로젝트 경로\ProjectSettings\GraphicsSetting.asset

위 경로의 파일을 메모장으로 열고

TransparencySortModeTransparencySortAxis를 직접 바꿔주면 된다.

 

CustomAxis로 사용하기 위해서는

m_TransparencySortMode를 3으로 설정하고
TransparencySortAxis를 원하는 값으로 바꾼 뒤
프로젝트를 재시작하면 적용된다.

 

+ URP 2D에서는 Renderer 2D 설정에서 TransparencySortMode를 설정할 수 있다.
GraphicsSetting에 작성한 TransparencySortModeRenderer2D 설정으로 덮어 씌워진다

블로그 이미지

stuban

ㅇ.ㅇ

,

 

맥과 윈도우를 번갈아서 사용할 때
윈도우에서 작성한 파일을 맥에서 수정하는 경우 한 글자만 변경하더라도 파일의 모든 부분이 변경되었다고 표시되었다.

OS마다 줄 끝을 처리하는 방식이 달라서 생기는 문제였는데.

git config core.autocrlf

위 설정을 통해 깃이 줄 끝을 자동으로 처리하도록 설정할 수 있다.

 

맥/리눅스의 경우 autocrlf를  input 구성으로 설정하면 문제가 해결된다.

$ git config --global core.autocrlf input
# Configure Git to ensure line endings in files you checkout are correct for macOS

이러면 깃이 알아서 줄 끝을 맞춰준다

 

아니면 윈도우에서 autocrlf를 true로 설정하면 된다.

$ git config --global core.autocrlf true
# Configure Git to ensure line endings in files you checkout are correct for Windows.
# For compatibility, line endings are converted to Unix style when you commit files.

autocrlf를 true로 설정하면 애초에 줄 끝을 유닉스 스타일로 맞춰줘
맥이나 리눅스에서도 호환성 문제 없이 작업할 수 있다.

 

https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings

 

Configuring Git to handle line endings - GitHub Docs

About line endings Every time you press return on your keyboard you insert an invisible character called a line ending. Different operating systems handle line endings differently. When you're collaborating on projects with Git and GitHub, Git might produc

docs.github.com

 

 

'프로그래밍' 카테고리의 다른 글

모든 질문에 답을 해주는 사이트  (0) 2017.10.16
블로그 이미지

stuban

ㅇ.ㅇ

,

 

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/features/rendering-debugger.html

 

Rendering Debugger | Universal RP | 16.0.0

Rendering Debugger The Rendering Debugger window lets you visualize various lighting, rendering, and Material properties. The visualizations help you identify rendering issues and optimize Scenes and rendering configurations. This section contains the foll

docs.unity3d.com

 

urp를 사용할 때

컨트롤 + 백스페이스 혹은
게임패드의 양쪽 스틱을 동시에 누르면

렌더링 디버그 창을 띄운다

 

나 같은 경우는 게임패드의 양쪽 스틱을 동시에 눌러 발동하는 스킬을 개발하고 있었는데
디버그 창을 띄우는 단축키와 동일해 문제를 겪고 있었다
(심지어 공식 문서에서도 끄는 법이 안나와 있음)

렌더링 디버그 창을 띄우는 단축키를 변경하고 싶다면

DebugManager.Actions.csRegisterInputs() 함수 내용을 수정해주면 된다.
(12.1.9 버전 기준 295번줄)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void RegisterInputs()
    {
#if UNITY_EDITOR && !USE_INPUT_SYSTEM
    var inputEntries = new List<InputManagerEntry>
    {
        new InputManagerEntry { name = kEnableDebugBtn1,  kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left ctrl",   altBtnPositive = "joystick button 8" },
        new InputManagerEntry { name = kEnableDebugBtn2,  kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "backspace",   altBtnPositive = "joystick button 9" },
        new InputManagerEntry { name = kResetBtn,         kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left alt",    altBtnPositive = "joystick button 1" },
        new InputManagerEntry { name = kDebugNextBtn,     kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page down",   altBtnPositive = "joystick button 5" },
        new InputManagerEntry { name = kDebugPreviousBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page up",     altBtnPositive = "joystick button 4" },
        new InputManagerEntry { name = kValidateBtn,      kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "return",      altBtnPositive = "joystick button 0" },
        new InputManagerEntry { name = kPersistentBtn,    kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right shift", altBtnPositive = "joystick button 2" },
        new InputManagerEntry { name = kMultiplierBtn,    kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left shift",  altBtnPositive = "joystick button 3" },
        new InputManagerEntry { name = kDPadHorizontal,   kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right",       btnNegative = "left", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
        new InputManagerEntry { name = kDPadVertical,     kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "up",          btnNegative = "down", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
        new InputManagerEntry { name = kDPadVertical,     kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Seventh, btnPositive = "up",    btnNegative = "down", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
        new InputManagerEntry { name = kDPadHorizontal,   kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Sixth,   btnPositive = "right", btnNegative = "left", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
    };
 
    InputRegistering.RegisterInputs(inputEntries);
#endif
 
#if USE_INPUT_SYSTEM
    // Register input system actions
    var enableAction = debugActionMap.AddAction(kEnableDebug, type: InputActionType.Button);
    enableAction.AddCompositeBinding("ButtonWithOneModifier")
        .With("Modifier""<Gamepad>/rightStickPress")
        .With("Button""<Gamepad>/leftStickPress")
        .With("Modifier""<Keyboard>/leftCtrl")
        .With("Button""<Keyboard>/backspace");
 
    ...    
 
#endif
    }
}
cs

 

난 인풋 시스템을 사용하고 있고
디버그 창을 띄우는 키를 게임패드의 스타트와 메뉴 버튼으로 바꿨다

1
2
3
4
5
6
var enableAction = debugActionMap.AddAction(kEnableDebug, type: InputActionType.Button);
enableAction.AddCompositeBinding("ButtonWithOneModifier")
    .With("Modifier""<Gamepad>/start")
    .With("Button""<Gamepad>/menu")
    .With("Modifier""<Keyboard>/leftCtrl")
    .With("Button""<Keyboard>/backspace");
cs

 

블로그 이미지

stuban

ㅇ.ㅇ

,

최근 알고리즘 공부가 필요할 것 같아서 고민하다

프로그래머스 라는 코딩 테스트 사이트에 도전하기로 마음먹게 되었다

프로그래머스에는 코딩테스트 고득점 Kit라는 섹션이 있는데

여기 있는 Kit의 유형들을 하나씩 공부할 예정

(참고로 유형에 있는 문제 해답은 공유 안할거임)

 

그래서 오늘 주제는 '해싱'이다

 

 


해싱은 키 값을 가지고 자료를 저장하는 방식을 말한다

 

 

보통 자료를 저장하는 곳은 배열로 되어있고 해시 테이블이라고 불리고

키 값을 이용해서 배열의 주소를 구하는 방식으로 되어있다

이때 키 값을 주소로 바꾸기 위해 해시 함수를 사용한다

 

해시 함수를 사용하면 자료가 있는 곳까지 바로 안내하기 때문에

이상적으로는 시간 복잡도가  O(1) 이 된다.

 

 

대강 그림을 그리자면 다음과 같다

 

 

> 해시 함수

 

해시 함수는 키 값을 해시 테이블의 주소로 변환하는 역할을 한다

 

해시 함수를 만들때 가장 중요하게 봐야할 것중 하나는 충돌 이다

 

해시 테이블의 크기는 한정되어있기 때문에 한 주소에 여러개의 키가 들어갈 수 있는데

이것을 충돌이라고 한다

 

충돌 예시

 

충돌이 많이 일어나면 자료를 다른 곳에 저장해야하고

그 다른 곳을 찾는 연산을 추가로 해야하기 때문에 탐색 속도가 느려지게 된다

 

따라서 좋은 해시 함수는 

1. 충돌이 적어야하며

2. 해시 함수 값이 해시 테이블의 주소 영역 내에 골구로 분포되어야하고

3. 계산이 빠를 수록 좋다

 

 

 

>해시 테이블

 

지금까지 나온 해시 함수중 충돌이 없는 함수가 없다고 한다

따라서 테이블도 충돌에 대비한 설계가 필요한데

 

2가지 정도의 해결책이 있겠다

 

1. 조사 (probing)

 

조사법은 특정 버킷(테이블의 구성요소를 버킷이라고 부른다)에서 충돌이 일어나면

해시 테이블에서 비어있는 다른 버켓을 찾는 방법이다

 

>선형 조사법 (linear probing)

 

만약 해시 테이블의 [n]번 버킷에서 충돌이 일어나면 [n+1]번 버킷이 비어있는지 확인하고

만약 거기도 차있으면 [n+2]를 살펴보는 식으로 차례차례 빈 공간을 찾는 것을 선형 조사법이라고 한다

 

 

>이차(제곱) 조사법 (quadratic probing)

 

선형조사법이 차례대로 조사하는 것이라면 이번에는 제곱수만큼 움직이는 것이다

만약 [n]번 버킷에서 충돌이 일어나면 [n+1²] 번으로 그 다음은 [n+2²], [n+3²], [n+4²] ...

이런식으로 찾아가는 것이다

 

>이중 해싱 (재해싱)  (double hashing)

 

이중 해싱은 해시 함수를 2개 만들어두고

만약 충돌이 일어나면 2번째 해시함수로 다시 해싱을 하는 방식이다

 

 

 

2. 체이닝 (chaining)

 

위와 같은 경우에는 버킷 하나당 고정된 양의 자료만 저장할 수 있어서

버킷이 꽉 차면 모든 테이블을 돌아다니며 자리를 찾아야 했고

해시 주소가 다른 탐색키와도 비교를 해야하기 때문에 시간이 많이 걸릴 수 있었다

 

만약 버킷에 슬롯을 만들어서 한번에 같은 해시 주소를 가진 여러개의 자료를 저장할 수 있게 한다면 어떨까?

 

체이닝은 연결리스트를 사용해 슬롯을 만든다

연결리스트를 사용하기 때문에

충돌이 일어나도 오버플로(버킷이 꽉 차는 경우)가 발생할일이 없고

삽입과 삭제가 수월해진다

 

 

 

 


 

 

하지만 실제로 프로젝트를 진행하면서 (심지어 프로그래머스 코딩테스트에서도)

별 특이한 경우가 아니고서야 실제로 사전 구조를 처음부터 만드는 일은 없을 것이다

그래서

 

C++에서는

<map>의 map

을 사용하고

 

C#에서는
System.Collections.Generic 의 Dictionary

를 사용할 수 있겠다

 

근데 프로그래머스 고득점 Kit 해시 문제 중에 절반은 해시 안 쓰는 게 더 간단하던데... 뭐지?

'프로그래밍 > 알고리즘,자료구조' 카테고리의 다른 글

퀵 정렬 (Quick sort)  (0) 2018.06.13
블로그 이미지

stuban

ㅇ.ㅇ

,

 

블로그 이미지

stuban

ㅇ.ㅇ

,
1
2
3
4
5
6
7
8
DELIMITER $$
create procedure NewUser (_id int, _name varchar(20))
begin
 
insert into user(id,name) values (_id , _name);
 
end$$
DELIMITER ;
cs

1 , 8 : DELIMITER로 처음과 끝을 감싸야 한다. (이유는 이전 글 참고)

2 : 프로시저 정의 (인자를 받지 않을 수도 있다)

3 , 7 : 시작과 끝

 

1
call test.NewUser(123,'bang');
cs

호출은 call 을 사용한다.(여기서 test는 프로시저가 있는 db이름)

'프로그래밍 > SQL' 카테고리의 다른 글

sql 함수 만들기  (0) 2019.08.07
mysql Limit  (0) 2017.10.22
sql의 주석  (0) 2017.10.19
유니티와 mysql 연동하기  (0) 2017.10.19
mysql 자동증가값(auto_increment) 가지고 오기  (0) 2017.10.13
블로그 이미지

stuban

ㅇ.ㅇ

,