내일배움캠프 15일차 TIL : 메모리 구조 특강, 유니티 질답 정리

woollim·2024년 10월 14일
1

내일배움캠프TIL

목록 보기
14/36
post-thumbnail

■ 학습 개요

오늘 계획

  • 유니티 입문 개인 과제(Sparta Town) 제출 및 코드 복기, 주석 달기
  • 유니티 강의 8강 ~ 16강 복습
  • 첼린지 특강(메모리 구조)
  • 유니티 관련 이해안되는 점들 튜터님께 질문

학습 회고

  • 과제에서 델리게이트를 많이 사용 못했다. 델리게이트로 변환 할 수 있는게 있다면 추후에라도 수정해야겠다.
  • 과제를 진행하며 유니티에 익숙해졌지만,구조나 원리에 대한 궁금증도 늘어났다. 주말동안 쌓아놨던 궁금증들을 튜터님께 거의 한시간가량 질문하고 설명을 들었다. 저녁이라 피곤하실텐데도 친절하고 상세하게 설명해주셔서 감사했다.
  • 챌린지반 특강으로 메모리 구조를 배웠다. 예전에 C++ 공부할때도 메모리 구조를 공부했었지만 C#은 가비지 컬렉터가 있고, 포인터, 레퍼런스 등이 없는 차이점이 있어서 평소 궁금했던 부분이었다.


■ 질답 정리

유니티 관련 질문들

  • Q1. Vector3에 값 두개만 넣으면 Vector2가 되는 건지, Vector2를 쓰면 안되는 건지 궁금합니다.
    protected float DistanceToTarget()
    {
    return Vector3.Distance(transform.position, ClosetTarget.position);
    }

    • Vector3에 값 두개만 넣는다고 Vector2 값이 되는 거 아님
    • 같은 Z 선상에 있는 것이면 Vector2를 써도 됨. 위 코드는 Vector2 써도 됨

  • Q2. InputSystem에서 Look 만든데로 입력하면 OnLook 함수가 호출되나요?
    (On+입력이름 으로 호출되는건가요?)

    • 함수명이 'On + 설정했던 Actions' 으로 생성 됨
    • Player Input 하단에 보면 쓸 수 있는 함수 이름이 표기되어 있음

  • Q3. 비주얼 스튜디오에 있는 TextMesh Pro 폴더는 뭔가요?

    • UI 중 TextMesh Pro 가 붙은 UI 를 이용하면 생성됨
    • Legacy UI 보다 성능이 좋다 (Legacy는 업데이트가 종료된 UI)
    • 한글 지원이 안되니 한글을 쓰려면 한글이 포함된 폰트를 추가해야함
    • 폰트 추가하는 법 링크

  • Q4. GetComponent는 오브젝트에 직접 추가된 Component랑은 관련없이 가져오는건가요?

    • 같은 오브젝트 Inspector 내에 있는 컴포넌트들을 가져와 쓸때 사용하는 코드
    • gameObject가 생략되어있음. gameObject.GetComponent
    • 같은 오브젝트 내에 있는 컴포넌트를 마찬가지로 같은 오브젝트 내에있는 각기 다른 스크립트가 접근해도 동일한 컴포넌트이다
    • AddComponenet가 새로 생성하는 것. 스크립트 실행 중에 Inspector를 확인하면 해당 컴포넌트가 부착된 것을 확인 할 수 있음
    • GetComponent 에서 "같은 오브젝트" -> "타겟 오브젝트" 로 보는 것이 좋음
    • 평소에는 gameObject 가 생략되어 나의 컴포넌트를 가지고 오는 것이지만, 대상이 있는 경우 해당하는 곳의 컴포넌트에 접근할 수도 있음. ex) targetPlayer.GetComponent<Player>().Hp;

  • Q5. Instantiate()는 어떤 때에 주로 활용되는지 궁금합니다.

    • 개발자가 해당 오브젝트가 몇개가 필요할지 모를 때, 유저 상황에 따라 다른 경우 등
    • 예를 들어 인벤토리(칸), 친구 목록, 참석자 목록

  • Q6. 델리게이트 연습 방법

    • 팝업창 만들어보기


■ 챌린지 특강 - 메모리 구조

메모리 구조

  • Data 영역 : 정적 변수, static

    • 프로그램(게임) 시작할때 Data영역에 할당 됨
    • 스태틱이 만들어져 있을 때는 힙과 스택은 이 메모리를 이용하는 것들은 아직 생성되어 있지 않기 때문에 사용할 수 없는 문제가 있었다
      (유니티에선 이런 문제가 크지 않음)
  • Heap 영역 : 참조 데이터(객체) 저장, 클래스, 배열, 문자열

    • 힙메모리에 할당되는애들은 어디(주소)에 할당되는지 모름(알 수 없음)
    • 클래스 변수는 스택에, 데이터는 힙메모리에
    • 클래스 변수엔 데이터 위치인 주소도 담겨있다
    • 더이상 참조(사용)하지 않는 데이터는 가비지 컬렉터가 언젠가 삭제한다
    • Destroy는 오브젝트만 삭제하고 데이터는 남아있다.(가비지로 남게 됨)
    • 가비지 컬렉터가 수행되기전엔 메모리가 낭비 되므로, 데이터를 한번 만들고 재활용하는게 좋음
  • Stack 영역 : 로컬 변수, 매개 변수, 구조체


인스턴스

  • GameManager의 instance와 같은 경우
  • static이므로 게임이 시작될때 Data 영역에 적재됨
  • 어디서든 객체 생성없이 instance로 접근이 가능함
  • start의 instance = this가 해당 객체를 할당해줌. 객체는 이미 만들어져있었음


유니티의 인스턴스

  • 아래 업데이트 문이 문제 없는 이유
  • Vector3는 구조체임, 구조체라서 Update에 있어도 괜찮음
  • 구조체는 call by value 형식이므로 가비지로 인한 메모리 낭비가 없다
  • 업데이트가 반복되도 같은 메모리 주소안에서 데이터를 재할당하기 때문에 공간 낭비가 없음
  • 가비지 낭비도 막고, 속도도 더 빠름(주소참조를 안해서)
  • 클래스였다면 무수히 많은 객체들이 가비지가 되어 메모리를 꽉채웠을 것


구조체와 클래스 차이점

  • 차이점 학습 정리 링크
  • 차이점을 알면 어느 상황에 어떤걸 쓰는게 좋은지 잘 선택 할 수 있음
  • 구조체는 속도는 빠르겠지만 외부 데이터 공유가 안되고, 상속등의 확장이 안됨
  • 클래스는 가비지가 생길 위험이 있고 구조체 보다 느림
  • 클래스는 장기적으로 참조하여 사용하는 용도
  • 구조체는 단지적으로 빠르게 데이터를 활용하는 용도 (Vector3)


문자열 연산과 메모리

  • 문자열 연산은 (불변 연산)
  • 문자열을 더해서 다른 주소에 저장
  • 문자열은 힙에 저장되므로 이전 데이터를 저장한 주소엔 가비지가 남음 -> 파편화 라고 함
  • 여러줄에 걸쳐서 문자열 연산을 하면 주소 여기저기에 가비지가 남아서 파편화가 심해짐
  • 한줄에 문자열 연산을 하는게 좋음 (이래도 새로운 주소에 생기긴 하지만 적어도 하나의 주소에서 연산하므로 낭비를 줄임)
  • 보간 문자열 방식을 추천함


스트링 빌더

  • 스트링 빌더가 파편화가 없는 이유는 단순히 해당 문자열보다 주소 공간을 처음 부터 많이 잡음
  • 공간을 넘으면 리스트처럼 재할당 한다 (2배로 늘림)
  • 스트링 빌더도 초기 길이를 정할 수 있음
  • 연산속도는 일반 문자열 연산과 비슷 파편화가 없기 때문에 스트링 빌더가 더 좋음

0개의 댓글