고갱
[스타듀 밸리] 3D 게임 개발 #3, 캐릭터 구현 & 물 변경 & Day-Night Cycle 추가 본문
요새 회사에서 외주받은 일을 처리하다가 생각치도 못하게 너무 빨리 끝내버려서 시간이 비었다.
해당 서비스가 성능이 좋지 않아서 남은 기간에 리팩토링을 해도 좋겠지만 기존 코드가 너무 얽히고 섥혀있어서 섣불리 건드렸다가 오히려 오작동을 일으킬 가능성이 있기 때문에 건드리지 않기로 판단하였다.
그래서 졸업 작품을 할까 게임을 만들까 고민하다가 잠깐 Unity를 켜보았다.
🤔 오늘의 진척 사항
오늘은 크게 몇 가지 진척 사항이 있는데 아래와 같다.
- 캐릭터 구현
- 물 변경
- Day-Night Cycle 추가
하나씩 살펴보자.
1. 캐릭터 구현
캐릭터 애니메이션에는 BlendTree와 StateMachineBehaviour 등 몇 가지 기능을 사용해서 구현하였다.
그냥 위지윅처럼 슥슥 끌어서 해결할 수 있을 정도로 간단하게 구현하지는 않았다.
(이럴 때 비유하는 위지윅이 아니지만, 그냥 표현하자면 그렇다는 것)

![]() |
![]() |
![]() |
![]() |
너무 길어지니 일부분만 표시하자면 이렇게 되어있다.
엎드리기도 구현되어있고 2단 점프도 구현되어있고 달리기도 구현되어있고 그렇다.
캐릭터에 카메라가 가까워지면 캐릭터가 Fade-Out 되는 것도 구현해두었는데 이 과정에서 골치 아팠다.
Shader를 공부한 적이 없으니 Shader를 하나하나 살펴보며 어느 부분을 수정해야 Transparency 를 적용할 수 있을 지...

결론은 사용하고 있는 에셋의 RPGViewFrustum 클래스를 상속하여 캐릭터를 투명화하는 클래스를 상속받아 재정의하여 해결하였다.
에셋 코드가 누구든 편하게 재정의할 수 있게 virtual 함수로 선언되어 있어서 재정의하여 사용하였다.

그리고 얼굴 부분이 뒤에서 보면 갑자기 잘려보이는 현상이 있었다.. Culling Mode를 Back으로 설정하면 해결되긴 하지만 그러면 앞에서 렌더링되지 않아 Both로 설정하였으나 잘림 현상이 다시 발생하였다..
이를 해결하기 위해서 Alpha Clipping 값을 매우 낮춰서 해결하는데 이것도 찾는 과정이 좀 오래걸렸다.
그리고 CrouchingState 라고 명시된 Sub-State를 보면 AnyState에서 CrouchingStart로 연결되게 구현해두었는데, 이렇게 되면 Can Transition To Self 가 해제되어 있더라도 Crouching 으로 상태가 넘어가는 순간 다시 CouchingStart로 넘어가기 때문에 StateMachineBehaviour 를 사용해서 Sub-State 안에 있는 경우 AnyState에서 넘어오는 것을 방지하게끔 구현해두었다.
❓ PropertyToId, StringToHash
그리고 왜 항상 Shader.PropertyToID 나 Animator.StringToHash 를 정적 변수로 설정해두는지 설명하자면 인터넷에 검색하면 많이 나오는데 성능 때문이다.
매개변수로 String을 넘겨주면 유니티에서는 이를 해시로 변환하여 수행하는데, 매번 String을 해시로 변환하여 수행하게 되면 성능상 이점이 나오지 않으니 사전에 변환하여 이를 직접 매개변수로 넘겨주면 성능이 빨라지는 것이다.
Unity - Scripting API: Animator.StringToHash
Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close
docs.unity3d.com
실제로 유니티 문서에도 StringToHash는 최적화된 getter와 setter에 사용된다고 나와있다.
(PropertyToID 도 동일한 원리)
2. 물 변경
사실 이건 굳이 변경해야하나 싶긴 했지만, 몇 가지 사항때문에 변경했다.
우선, 아직도 많은 정점 수이다.
지난 주 DFS 알고리즘을 통해 웅덩이에 맞게 Mesh를 조정해주는 작업은 진행하였지만, 사실 조정하더라도 정점 수가 만 개를 넘어섰다.
물론 점점 기기들의 성능이 올라가기 때문에 문제가 되지 않을 뿐더러, 쉐이더 등과 같이 정점 수보다 성능에 영향을 미치는 요소가 많기 때문에 이는 굳이 변경할 필요는 없다.
두 번째로는 번짐 현상이다.

자세히 보면 물에서 반사를 구현한 부분에서 다소 이상한 점이 있었다.
옆이나 위에 있는 오브젝트가 번지듯이 보이는 현상이었는데 쉐이더를 수정해볼까 하다가 겸사겸사 바꾸기로 결정하였다.
❗ 변경 후 모습
![]() |
![]() |

이번에 새롭게 적용한 물 표면은 이전과 다르게 전체를 덮어도 169개의 정점 수로 낮아진 수치이다.
또한 DFS 알고리즘을 수행할 필요가 없어지기 때문에 CPU의 부하가 줄어들 수 있어 좋다.
3. Day-Night Cycle 추가
마지막으로 밤 낮, 날씨의 구현인데 이건 Enviro 에셋을 써서 구현하였기 때문에 별도로 설명할 게 없다.
Enviro - Sky and Weather | Particles/Effects | Unity Asset Store
Use the Enviro - Sky and Weather tool for your next project. Find this and more particle & effect tools on the Unity Asset Store.
assetstore.unity.com
상당히 퀄리티가 좋아 예전부터 애용했던 에셋 중 하나다.
😵 다른 진척 사항
그리고 번외로 지난 주 Noise를 계산하는 Job에서 변경점이 있다.
기존에는 JobSystem 내부에서 noise 연산을 수행할 때 FastNoiseLite 클래스를 Job 내부 함수에서 생성하여 연산을 수행하였는데, 이렇게 하는 경우 각 병렬 작업이 실행될 때마다 해당 클래스의 인스턴스가 생성되고 사라지기를 반복하기 때문에 이를 전역 변수로 바꿔주었다.
단, FastNoiseLite는 클래스이기 때문에 Job 내부에 전달할 수 없다는 점을 근거로 FastNoiseLite를 구조체로 변환하여 넘겨주었다.

만약 클래스를 넘겨주면 아래와 같이 오류가 나타난다.
InvalidOperationException: 이름.변수이름 is not a value type. Job structs may not contain any reference types.
Unity - Manual: Job system overview
Job system overview Unity’s job system lets you create multithreaded code so that your application can use all available CPU cores to execute your code. This provides improved performance because your application uses the capacity of all the CPU cores it
docs.unity3d.com

보면 나와있듯이 Job-System은 메인 스레드의 코드에서 데이터에 대한 참조를 보내면 경쟁 조건을 생성한다고 명시되어 있으므로 참조형을 포함하지 않게끔 하고있음을 알 수 있다.
근데 아직 뭔가 2% 모자란 최적화 같아서 조금 더 고민해볼 수 있을 때 고민해보던가 해야겠다.
👍 참고 자료
PropertyToID 함수
Unity - Scripting API: Shader.PropertyToID
Using property identifiers is more efficient than passing strings to all material property functions. For example if you are calling Material.SetColor a lot, or using MaterialPropertyBlock, then it is better to get the identifiers of the properties you nee
docs.unity3d.com
StringToHash 함수
Unity - Scripting API: Animator.StringToHash
Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close
docs.unity3d.com
Job System
Unity - Manual: Job system overview
Job system overview Unity’s job system lets you create multithreaded code so that your application can use all available CPU cores to execute your code. This provides improved performance because your application uses the capacity of all the CPU cores it
docs.unity3d.com
Day-Night Cycle 에셋
Enviro - Sky and Weather | Particles/Effects | Unity Asset Store
Use the Enviro - Sky and Weather tool for your next project. Find this and more particle & effect tools on the Unity Asset Store.
assetstore.unity.com
'게임 개발 > Unity' 카테고리의 다른 글
| [셰이더] Curved World 수동 구현 (0) | 2026.01.05 |
|---|---|
| [학교 과제] 3D 게임 개발 #2, 게임 로직과 멀티 플레이 1차 구현 (0) | 2025.05.27 |
| [학교 과제] 3D 게임 개발 #1, 로직 변경 (0) | 2025.05.17 |
| [스타듀 밸리] 3D 게임 개발 #2, 지형 최적화 (2) | 2025.01.09 |
| [스타듀 밸리] 3D 게임 개발 #1, Perlin Noise를 이용한 지형 생성 (0) | 2025.01.07 |






