ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] 10주차 5일 ( 유니티에 관한 꿀팁 (심연))
    개발일지/스파르타 코딩클럽 부트캠프 2024. 6. 21. 21:59

     

    오늘 특강에서 배운 부분을 TIL로써 채워볼까 한다.

    이번 특강에서는 튜터님의 유니티를 향한 시선과, 유니티를 활용한 개발에 있어서 있는 꿀팁과 중요 정보들을

    많이 알 수 있었다.

     

    튜터님의 Unity에 영화를 빗댄 시선

    Unity - 영화

    • Scene  - 영화 촬영 장소
    • Game - 실제 영화의 결과물
    • Hierarchy - 영화에 출연하는 배우들
    • Inspector - 각 배우들에게 주어진 역할들
    • Project - 창고(다른 씬에서 사용할만한 소품, 배우들이 저장되는 공간)
    • Script - 배우들에게 주어지는 대본

    Prefab

    Prefab을 만들고 하이어라키 창에서 수정을 한 후 다시 프로젝트에 넣으려고 할 때

    우린 이런 창을 볼 수가 있다.

    각각 무슨 뜻일까?

     

    Original Prefab - 아예 독립적으로 새로 만들어지는 Prefab

    Prefab Variant - 원본을 보유한채로 약간의 변형을 적용한 Prefab의 자식 객체로 사용

    Prefab Variant는 상속의 개념과 비슷하다.

     

    예를 들어서 원본의 Prefab을 하이어라키 창에 꺼내어 각자 얼굴, 팔, 다리 를 달아줬다.

    그리고 3개의 Prefab Variant를 프로젝트에 넣으면 얼굴, 팔, 다리를 가진 프리팹 3개가 생긴다.

    이 상태에서 원본 Prefab에 머리카락을 넣으면 나머지 3개의 Prefab Variant에도 다 머리카락이 추가된다.

     

    Target을 찾는 여러가지 방법

     

    1. public을 통해서 다른 객체의 값을 불러오기 ( 인스펙터 창에서 )

    2. GameObject.Find("name") << 그냥 쓰면 성능이 너무 안좋음

    • GameObject.FindGameObjectWithTag();
    • GameObject.FindObjectOfType<반환을 원하는 Type ex) Target, Player, Enemy>()

    ?시간 복잡도?

    Tag로 하든 type으로 find를 하든 hierarchy 전부를 탐색하는건 똑같은데 string으로 값을 찾는 것을

    방지하기 위해서 Tag나 Type으로 찾게 하는 것일까?

     

    문자열은 참조타입이라 힙에 들어가면 GC가 발생해서 되도록 쓰지 않는다.

    • 비활성화 된 객체는 찾을 수 없다.
    • Find 자체의 성능이 좋지 않기 때문에 사용을 최소화 하는 것이 좋다.

    여기서 GC란?

    GC는 가비지 컬렉션 ( Garbage Collection ) 의 약자로

    메모리 관리 방법 중의 하나이다. 프로그래머가 동적으로 할당한 메모리 영역 중 더 이상 쓰이지 않는

    영역을 자동으로 찾아내어 해제하는 기능이다.

    GC가 발생하거나 객체가 각 영역에서 다른 영역으로 이동할 때 애플리케이션의 병목이 발생하면서 성능에 영향을 주게됩니다.

     

    MonoBehavior

     

    Start, Update, StartCoroutine, Invoke, GetComponent 등의 함수들을 사용 가능하게 해주는 객체


     

    이제 흑마법을 좀 알아볼건데.... 튜터님도 가르쳐주시면서 사용은 절대 하지 말라고 하셨던 만큼

    혹시 제 글을 읽으시는 분도 사용은 하지 마시기 바랍니다. 심연을 보시죠

     

    private인 객체의 함수를 사용할 수 있는 방법 ( Script에서 절대 사용하지 말것 디버깅이 안됨 )

     

    Monobehavior에서 객체의 함수를 찾아 실행

    • target.SendMessage("Catch");

    Monobehavior에서 해당 객체의 자식까지 탐색 + 함수를 찾아서 실행

    • target.BroadcastMessage("Catch");

    Update를 존재시키는 것 자체가 성능 저하

     

    Update() 함수가 존재할 경우 Unity 코어에 자동으로 등록하기 때문에, 내용이 아무것도 없더라도

    해당 생명주기 함수가 계속해서 돌아간다. 안쓰면 지우자

     

    UI

    캔버스를 적당히 나눌 것

    Canvas 내용에서 하나 수정할 떄마다 Canvas안의 내용을 전부 다시 그려야함

    변동이 없는것, 변동이 있는 것으로 나눠서 빼면 좋다.

    - 이유는 Canvas안의 단 하나의 UI에만 변동이 생겨도 Canvas 전체를 다시 그린다 = 최적화에 문제

     

    구도 잡기

     

    Manager

    1. GameManager
    2. DataManager
    3. ResourceManager
    4. AudioManager
    5. UIManager

    보통 우리가 하는 Manager 제작

    1. Script

    • 각 객체별로 Singleton 셋팅
    • Generic Singleton을 작성해서 Manager별로 상속

    2. GameObject

    • 각 객체들을 만들어서 Script를 붙혀놓는다.

    과연 이게 좋은 방법인가? 에 대한 이야기

     

    다른 방법 )

    GameManager만 싱글톤

     

    GameManager의 모호했던 역학을 Manager를 관리하는 총괄매니저 느낌으로 변경

    하나의 오브젝트를 통해서 모든 매니저를 관리 가능

     

    각각의 Manager들에서 Monobehavior를 떼고 GameManager에서 생성 및 관리

    1. 속도에서 약간의 이점이 있다.

       - 다만 로직에 따라 다를 수 있다.

       - 메모리 파편화를 막을 수 있다.

    2. 코드 작성 시에 접근하기 편하다

    3. 구조를 다양하게 짜는 것이 좋다.

     

    Manager가 MonoBehavior를 사용해야하는 경우 따로 singleton을 잡는게 맞다.( 첫 방법처럼)

     

    [기존 - Monobehavior O]


    • 각 객체에서 Awake, Start함수를 수행
    • 각 Manager의 Start 를 수행 (2+ ms)
    • 각 Manager들이 메모리 공간에 파편처럼 흩어져 있다.

    [신규 - Monobehavior X]


    • 객체에서 Init() 함수를 생성하고 GameManager에서 시작할 때 호출
    • 하나의 Start를 수행 (1+ ms)
    • 같은 메모리 공간에 우르르 모여있다.

    string을 사용해야 하는 경우에는 데이터를 따로 뺴놔서 오타 나는 경우를 최소화한다.

     

    GetComponent의 경우는 필수불가결적인 요소들 빼고는 Awake에서만 사용하기

     

    이상 동기 박현호 님께서 정리해주신 내용을 바탕으로 TIL을 작성해봤다.

Designed by Tistory.