팀 과제 시작 후 역할 분담의 시간을 가졌음
이번 주제는 자유주제 장르는 공포 현재 맡은 역할은 Navmesh AI를 이용한 적 구현
전체적으로 팀 빌딩은 마치고 폴더링 후 제네릭 싱글톤만 구현하고 변경사항을 적용시켜 기본 틀을 만들어두었다.
새로 배우거나 좀 더 확실히 알게 된 개념
1. 제네릭 싱글톤 개선점
이번에 제네릭 싱글톤을 다같이 만들면서 DontDestroyOnLoad 할 싱글톤과 아닌 싱글톤을 기능을 나누어서 하려했는데
처음엔 두개의 제네릭 싱글톤 스크립트로 나누어 관리를 하려고 하였다. 그렇지만 만들고보니 비슷한 기능의 스크립트를 두개로 만들어 관리하는 것이 좋은 지에 대해 의구심이 좀 든다.
그래서 팀원분의 조언을 참고하여 두개의 싱글톤으로 구현하는 것이 아닌 상속시키는 클래스에서 커스텀하여 적용하는 식으로 하기로 하였다. 밑의 스크립트는 개선한 내용의 스크립트를 담고있다.
먼저 상속하는 클래스 쪽에서 똑같이 제네릭 싱글톤을 구현한 후 Virtual 키워드로 DontDestroyOnLoad 기능을 구현할 것인 지 여부를 정해준다.
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<T>();
if (_instance == null)
{
GameObject obj = new GameObject(typeof(T).Name);
_instance = obj.AddComponent<T>();
}
}
return _instance;
}
}
protected virtual void Awake()
{
if (_instance == null)
{
_instance = this as T;
DontDestroyOnLoad(_instance);
}
else
{
Destroy(gameObject);
}
}
}
상속받는 클래스에서는 base.Awake() 하여 기능을 구분해 하나의 싱글톤을 운영하는 방식으로 바꾸었다.
public class GameManager : Singleton<GameManager>
{
protected override void Awake()
{
base.Awake();
}
}
이를 통해 좀 더 안정적인 제네릭 싱글톤 운용을 해볼 수 있을 것이다. 이후 오류가 있다면 분석하여 수정하는 쪽으로 운용해보기로 하였다.
2. Vector
오늘 특강에서는 최종 프로젝트 전에 유의할 사항 등을 정리해보는 시간을 가졌다.
Vector는 방향과 크기를 정의하는 단위이다.
Vector 에 대해서 자세하게 알아보자면 덧셈 뺄셈 스칼라 곱으로 볼수 있다.
일단 시간상 많은 것을 정리할 수 없을 것 같기에 덧셈과 뺄셈만 더 정리해본다.
덧셈을 먼저 보자면
덧셈은 두 방향과 크기의 합이다.
아래의 공식문서의 예제를 보았을 때 (3,5) + (2,-1) 를 하였을 때 (5,4)가 되는 것을 이해하려면
(2,-1)이 어떻게 그려지는 지 상상해볼 수 있어야한다. (0,0) 에서 (2,-1) 로 이어진 선을 생각해본다면
아래 예제의 b와 같은 방향과 크기의 선을 볼 수 있을 것이다.
즉 여기서 우리가 알 수 있는 건 위치는 중요한 것이 아니라는 것이다. 방향과 크기가 만 같다면 그것은 같은 벡터라고 할 수 있다.
뺄셈은 덧셈과 약간 다르게 접근해야한다.
뺄셈은 두 지점 사이의 크기와 방향을 구한다.
아래 예제를 보았을 때 지점 b 에서 a 를 뺐을 때 (5,4)가 계산되었다. 이것은 a가 b까지 가는 데 있어
방향과 크기를 구한 것으로 두 지점이 멀수록 거리가 멀어지기에 같은 시간동안 가려면 그만큼 크기가 커지는 것이다.
방향 자체는 같더라도 가는 데 필요한 힘의 크기가 달라지는 것을 이용하여 우린 물리연산에 이를 속도로 이용하는 것이다.
카메라가 플레이어를 쫒아가게 할 때 cam의 transform position 값을 player의 tranform position 값에 빼는 것도 같은 원리이다.
magnitude
//크기만을 다루고 싶을 때
normalize
//방향만을 다루고 싶을 때
//이 때 크기는 1이 된다.
벡터는 힘과 방향을 나타내기 때문에 가끔 이 크기와 방향만을 다루고 싶을 때가 있다. 우리가 계속 배웠던
magnitude와 normalize는 그것을 위해 만들어진 키워드였다.
3. 최종 프로젝트 전에 알아둘 것
1. 폴더링을 잘하자
협업을 하는 데 있어 그리고 나 자신에게도 있어 폴더링을 잘하면 작업하는 데 도움이 된다.
01.Scene //자주 쓰이는 순으로 배치
02.Scripts
.
.
.
.
99.Assets // 유료에셋 이유는 따로빼두어 숨겨야할 때를 대비해 멀리 떨어진 숫자로 배정
2. 안쓰는 생명주기 함수를 지우자
안쓰는 생명주기를 지우는 이유는 MonoBehaviour 를 상속받았을 때 생명주기 함수를 리플렉션을 사용해서 호출하는 방식이라 안쓰고 있더라도 성능을 잡아먹는다.
3. 다 쓴 Debug.Log는 지우자
빌드할 때 디버그로그 또한 출력되어 성능 상 문제 그리고 해킹에 실마리를 줄 수 있다.
이를 사전에 방지하고자 한다면 아래 코드를 사용하여 디버그하는 것도 방법이다.
Debug.Assert (조건,false면 뜨는 로그)
Debug.LogAssertion(""); // 빌드를 쓸 때 제외됨
4. Linq 의 남용은 피하자
Linq가 편리하긴 하지만 Linq로 구현 가능한 것은 for 와 if로도 구현이 가능하다.
Linq는 .netFramework에서 호환해서 동작하는 방식이기에 많이 쓰면 성능에 좋다고 하기 힘들다.
5. 문자열끼리 덧셈은 피하자
문자열끼리의 합은 힙 스택과 가비지컬렉터의 원리로 이해하여야 한다.
요약하면 성능에 안좋다.
stringbuilder 사용을 권장한다.
6. 코루틴 유의점
코루틴을 쓸 때 while (true) 안에 new WaitforSeconds를 선언하는 것 처럼 사용된다면
계속 객체를 생성하기 떄문에 언젠가 가비지컬렉터가 회수하러 올 때 게임이 멈춰버린다.
WaitForSeconds wait 처럼 미리 캐싱을 해놓고 사용함이 현명하다.
7. 오브젝트 풀을 꼭 활용하라
모든 생성되고 파괴되는 것들은 오브젝트 풀로 성능부하를 미리 사전에 방지하여야 한다. (미리 로딩 시간에 받아놓자는 것)
일반적인 오브젝트 뿐 아니라 사운드와 파티클 등도 오브젝트 풀로 관리해야한다.
그리고 오브젝트풀로 생성되는 객체는 자식 오브젝트로 두면 그것 또한 성능에 영향을 주므로 최상단 계층에서 운용하는 게 낫다.
8.언박싱을 피하라
값 참조를 넘나드는 행위도 가비지 컬렉터를 유발한다.
진짜 필요한 상황이 아니라면 자제하는 것이 좋다.
'TIL' 카테고리의 다른 글
2024 11 19 TIL (2) | 2024.11.19 |
---|---|
2024 11 18 TIL (0) | 2024.11.18 |
2024 11 14 TIL (0) | 2024.11.14 |
2024 11 13 TIL (0) | 2024.11.13 |
2024 11 12 TIL (0) | 2024.11.12 |