개인적으로 언리얼을 혼자 배울때 제일 막막했던것이

무엇을, 어떻게 해야하냐는것이었다.

 

혼자 배울땐 필요하다 싶어서 해봤지만 실제로 회사가서 전혀 쓰지 않는것도 있고, 그 반대의 경우도 많아서

이참에 간단한 가이드를 작성해볼까 한다.

 

말은 간단한 가이드지만 기본적인 언리얼 이론은 싹 훑고 지나갈 예정.

 

* 타겟 언리얼 엔진 버전 : 5.1~ (최신버전)

--------------------

1) 언리얼 엔진 설치

 

우선은 설치부터 하자.

 

검색창에 에픽런쳐/언리얼엔진 정도로 검색해서 에픽게임즈 런쳐를 받아준다.

 

 

물론, 에픽게임즈 가입해야하니까 꼭 가입해두고..

 

 

 

설치가 종료되고, 실행하면 런쳐 페이지가 나오는데

저어기 좌측에 언리얼 엔진 눌러준다.

 

 

 

 

다음에 이런 페이지가 나오는데 저기서 엔진 설치를 눌러준다.

 

 

 

 

다운로드는 시간이 걸리니, 그동안 학습에 필요한 자료 몇개를 받아주자.

 

마켓플레이스 탭으로 간다.

 

 

 

여기서 무료 -> 에픽게임즈 콘텐츠 로 이동

 

여담이지만, 이달의 무료 콘텐츠에 좋은것들 잘 뜨니까 볼때마다 눌러서 받아주면 좋다.

 

 

 

 

에픽게임즈 콘텐츠에서 아래 두가지 항목을 찾아준다.

 

이 글을 쓰는 시점에는 2페이지에 바로 보이나, 안보이면 검색해서 찾아보도록 합시다.

 

 

카트에 추가 -> 구입하여 라이브러리로 받아두도록 합시다.

 

 

 

 

다시 라이브러리 탭으로 오면,

 

스크린샷과 같이 콘텐츠 보관함에 2개 (혹은 그 이상)이 추가되어있을 것이다.

 

엔진 용량이 큰 편이니 전부 받아질때까지 기다립시다.

 

만일 비주얼 스튜디오 등 IDE가 설치되어있지 않다면 지금 설치해두면 좋습니다.

 

 

 

한참을 기다리면... 

이렇게 엔진 설치가 완료됩니다.

 

 

 

이제 엔진을 켜봅시다.

 

사실 엔진을 켜면 제일 처음 맞딱드리면서 당황하게 되는게

1. 좌측에 뭐 저래 많아요?

2. 우측에 디폴트는 뭐 눌러야해요?

 

이거 두가지인데...

 

사실 답은 간단하다.

1. 좌측에 있는거 - 무시하세요

2. 우측에 디폴트 - 그냥 기능개발 프로토타이핑 할거 아니면 C++로 프로젝트 시작하면 됨

 

 

우선, 아무거나 프로젝트를 만들어보고 이리저리 굴려봅시다.

 

적당히 템플릿 하나를 고르고, 프로젝트 이름을 짓고 실행하면

이런 친구가 뜹니다.

 

최초 실행시에는 셰이더 컴파일 시간이 좀 걸려서...

 

엔진 로딩 시간이 좀 걸리니 진득하게 기다려주면 됩니다.

 

 

 

전부 준비가 되면..

웰컴 투 언리얼엔진

 

이제 이런 화면을 마주하게 됩니다.

 

축하합니다! 당신은 이제 언리얼 엔진 개발자로써 첫 걸음을 내딛었어요!

 

 

다음장에서는 기본적인 조작, 세팅, 그리고 블루프린트에 대한 간략한 설명을 해드리겠습니다.

 

 

 

---------기타 흔히 나오는 질문들-----------

1. 언리얼 개발하려면 컴 사양 좋아야한다는데 얼마나 좋아야 해요?

https://docs.unrealengine.com/5.1/ko/hardware-and-software-specifications-for-unreal-engine/

 

하드웨어 및 소프트웨어 사양

언리얼 엔진으로 개발할 때 필요한 최소 및 권장 하드웨어 및 소프트웨어 사양

docs.unrealengine.com

공식 문서 보시면 답이 나와 있습니다.

 

 

 

2. 언리얼할때 C++ 꼭 알아야하나요?

당연한걸 왜 묻죠?

 

 

 

3. 언리얼 엔진을 코드레벨부터 볼 수 있는 방법이 있다던데...

그건 다음에 설명드리겠습니다. (에픽게임즈 Git 저장소에서 코드 받아서 빌드하는 방법이 있음)

지금 회사에 취업해서 언리얼 만진지도 대충 6개월이 지났다

 

이제는 기본적인 개발은 수행할 수 있다고 생각을 하는데...

 

혼자 공부할때를 좀 되짚어보면, 언리얼은 사실 혼자 접하기에는 굉장히 난해하다고 생각한다.

 

일단 무엇보다, 뭘 써야하고 뭘 배워야 하는지 조차 접근하기게 에매해서, 어떻게 시작할지도 모른다는점이 제일 큰 장벽이라 생각된다.

 

그래서...

 

한번 내가 배웠던 과정을 되짚어가면서 (복습도 할겸) 가이드라인을 한번 써볼까 한다.

 

 

 

 

기본 독자 대상 : C++ 지식이 있고, 유니티 등 게임 개발에 기본적인 지식이 있는 사람

 

목표 : 언리얼 다운로드 부터 언리얼로 미니 프로젝트 하나 만들기까지

 

 

한 30부 생각중인데 아마 일주일에 한두편씩 쓴다치면 반년 걸리지 않을까?

만들어줄법한데....

 

안만들어주면 직접 만들어야지 뭐... 

'신변잡기 > 일상' 카테고리의 다른 글

하찮은걸 만들고 있습니다...  (0) 2024.02.11
오랫만에 개인작을 할까 합니다...  (0) 2024.02.08
근황  (0) 2022.04.25
오늘 있었던 일  (0) 2021.02.01
올해의 목표  (0) 2021.01.03

열심히 언리얼 5 만지고 있습니다. 

 

이번에 새로 작업하는 프로젝트에서 사용하는 오픈소스가 있어서 기록 남길 겸 + 한국어 문서가 전혀 없어서 직접 만들겸 해서 카테고리 하나 팠음... 

'신변잡기 > 일상' 카테고리의 다른 글

오랫만에 개인작을 할까 합니다...  (0) 2024.02.08
PC 카톡은 왜 삭제기능이 없을까...  (0) 2022.11.20
오늘 있었던 일  (0) 2021.02.01
올해의 목표  (0) 2021.01.03
근황 2  (0) 2020.10.15

만일 함수 안에서 무언가를 작성하는데 해당 문제를 발견했다면

 

함수 const가 아닌지 확인해볼것.

 

함수 뒤에 붙는 const는 "내부의 값이 변하지 않음"을 보장하는 한정자이므로, 내부에서 값을 변경시도하면 해당 오류가 발생한다.

 

찾아봤는데 없어서 적어둠..

'프로그래밍 > C/C++' 카테고리의 다른 글

std::sort()  (0) 2024.09.03
단방향 링크드 리스트 뒤집기 (C/C++)  (1) 2024.07.23
기록용 : 메모리 누수 찾기  (0) 2021.07.18
짧은 기록  (0) 2021.06.18
포인터 변수 사용시 데이터 오염 문제  (0) 2020.11.28

적으려고 하다보니 쓰레드 관련 내용이 하도 많아서 쓰레드부분만 분리하려고 새 글 팠음...

 

 

아래 내용은 'Windows via C/C++'을 기반으로 하고 있습니다.

 

* 틀린거 많으니 교차검증 꼭 하세요 *


[1] 스레드

  1. 스레드 이론
    1. 스레드란? : '작업 흐름', 코드를 수행하는 흐름 단위. 프로세스의 주소 공간내에 있는 코드를 수행하고 데이터를 이용함.
    2. 스레드에는 '스레드 커널 오브젝트' (운영체제가 관리하기 위한 커널 오브젝트) / '스레드 스택' (코드 수행시 필요한 데이터를 담아두는 스택)이 포함
    3. 하나의 프로세스 내에 둘 이상의 스레드가 존재 할 수 있음. 이때 스레드들은 단일 주소 공간을 공유하며 동일한 코드를 수행할 수도 있으며 동일 데이터를 조작할수도 있음.
    4. 커널 오브젝트 핸들 테이블은 스레드별이 아닌 프로세스별로 존재함으로 동일 프로세스 내의 스레드들은 커널 오브젝트 핸들도 공유하게 됨
    5. 프로세스는 스레드보다 더 많은 리소스를 사용하기 때문에 프로세스를 생성하는 대신 추가적인 스레드를 생성하여 사용하는편이 좋음. 하지만 때때로는 추가적인 프로세스를 생성하는것이 더 좋을 수 있음.
      (ex : 구글 크롬의 경우 멀티프로세스를 생성하여 작동시키는 방법을 사용함)
  2. 스레드 이론 2
    1. 스레드 생성이 필요한 경우 : 스레드 별 우선순위를 설정하여 일부 작업을 백그라운드로 밀어 작업을 수행하게 하거나 입력 / 출력등의 중요한 업무를 분리시켜 작업할 수 있음.
    2. 스레드 생성을 하지 않아야 하는 경우 : 다중 스레드로 인해 동일 파일에 입출력이 동시에 적용되는경우 (프린트 되는 문서에 직접 수정가하는 등), 사용자 인터페이스 같은 단일화가 필요한 작업은 멀티 스레드를 사용하지 않는것이 좋음
    3. 멀티스레드보다 멀티 프로세스를 사용하는 경우 : 애플리케이션 내부의 실행단위를 독립적으로 수행하는 경우. (메모리를 공유하지 않고 독립적으로 사용하는 경우) 구글 크롬의 경우 각 탭별로 다른 프로세스를 할당하여 타 탭이 꺼지더라도 앱 전체가 꺼지지 않음.

[2] 스레드 스케쥴링

  1. 스케쥴링 기본 :
    1. 스레드는 정지(Suspended), 대기(Wait), 실행 (Run) 상태를 가짐. 정지된 스레드는 스케쥴링될 수 없음.
    2. 'Suspended thread' 명령 수행시, 커널모드에서 수행중인 코드는 비동기적으로 수행을 완료하나, 유저모드에서 수행중인 코드는 즉시 정지됨. (메모리 잠금이 일어날 수 있음)
      따라서, 해당 명령은 정지시키고자 하는 스레드가 어떤 작업을 수행중인지, 정지시 생길 수 있는 문제점과 해결책을 명확하게 파악한 후 사용해야함.
    3. 특정 프로세스 내 스레드를 전부 순회하며 정지를 시키면 프로세스를 정지시킨것과 유사한 효과를 낼 수는 있음. 하지만 자주 쓰이지는 않음.
    4. 스레드는 sleep() 함수를 호출하여 일정시간동안 스케쥴링 대상이 되지 않도록 명령을 내릴 수 있음. sleep 호출시 스레드는 자신에게 남은 Time slice (할당시간)을 포기함.
      함수의 인자로 ms 단위의 시간을 제공할 수 있으며, 0을 입력할 수 있음.
  2. 스레드 우선순위 :
    1.  

[3] 스레드 동기화

  1. 유저모드 동기화 :
    1. 동기화란? : 다수의 스레드가 공유 리소스에 접근해야 하며, 리소스가 손상되지 않아야 하는 경우, 특정 스레드가 타 스레드에게 작업이 완료되었음을 알려야 하는 경우에 이루어지는 행동. 이 경우 각 스레드들은 상호 통신을 수행함. 
      동기화가 수행되지 않으면 데이터 오염 및 경쟁-교착상태(Race Condition)에 빠질 수 있음
    2. '원자적 접근' (Atomic) : Atomic은 일반적으로 'Instruction 단위' (명령어 수행 단위)를 의미함. 특정 리소스에 Instruction 단위로 수행중일 때, 타 스레드는 동일 시간에 동일 리소스로 접근해서는 안됨.
    3. 인터락 : 명령 수행중 인터럽트 되지 않고 값을 원자적으로 조작할 수 있음. 인터락 함수를 사용 시 값의 변화를 보장 할 수 있으나, 인터락 함수의 대상인 리소스는 타 함수 (인터락이 아닌 함수)가 호출해서는 안됨.
      인터락 함수는 유저모드/커널모드 전환을 일으키지 않으며 속도가 매우 빠름.
      인터락 함수로 전달되는 값은 반드시 메모리 상에 정렬되어 있어야 함. (아니면 호출 실패)
    4. 스핀 락 : 공유 리소스 사용시 리소스 사용여부를 지속적으로 검사하는 방식. (Busy Wait)
      스핀락은 CPU 시간을 많이 낭비할 수 있으며, 스핀락을 사용하는 모든 스레드가 동일한 우선순위에 놓여 있어야만 함.
      또한, 스핀락 변수와 락을 걸고자 하는 데이터는 서로 다른 캐시 라인에 있는것이 좋음. 동일 캐시 라인이라면 리소스 사용중인 CPU는 동일 리소스에 접근하고자 하는 타 CPU와 경쟁하게 될 것.
      단일 코어 프로세서에서는 스핀락을 사용하지 않는것이 좋음. (CPU 시간 낭비)
    5. 크리티컬 섹션 : 공유 리소스에 대해 배타적으로 접근해야 하는 코드 집합. 공유 리소스를 다루는 여러줄의 코드를 "원자적으로 수행"하기 위한 방법.
      여기서 원자적이란, 위에 적힌것과 같이 현재 스레드가 리소스에 접근중일때는 다른 스레드가 동일 리소스에 접근 할 수 없음을 의미.
      크리티컬 섹션 사용시에는 Enter -> Leave 순으로 함수를 호출해야하며, Enter시 타 스레드가 크리티컬 섹션의 데이터를 사용 시 진입 불가, 미 사용시에는 진입이 가능하여 사용 할 수 있다.
      크리티컬 섹션 사용시, 데이터를 사용완료하고 나면 반드시 Leave를 호출해주어야 한다. (그렇지 않으면 나머지 모든 스레드가 해당 자원을 사용하지 못하게 됨)
    6. 크리티컬 섹션 2 : 크리티컬 섹션에 진입한 스레드가 매우 빠르게 자원을 리턴하여, 이후 스케쥴링 타임까지 시간이 낭비되는 등의 경우를 방지하기 위해 크리티컬 섹션 사용시 스핀락 메커니즘을 투입하여, 리소스 획득을 반복적으로 검사하게 할 수 있음. 
      크리티컬 섹션에 스핀락 메커니즘을 사용시, 일정 시간동안 스핀락을 수행하며 공유 리소스의 자원획득을 시도하고 실패시 스레드를 대기시키기 위해 커널모드로의 전환을 시도 함.
    7. SRWLock (Slim Reader-Writer Lock) : 크리티컬 섹션과 유사하나 값을 읽는 Reader와 값을 쓰는 Writer가 분리되어 있음. 공유 리소스에 동시에 Read를 실시하는것은 공유 리소스 값을 손상시키지 않기 때문에 동시에 다수의 수행이 일어나더라도 상관없음. 단, Writer가 리소스를 수정하는 동안에는 어떠한 Reader/Writer도 추가적으로 접근 해서는 안됨
    8. 조건변수
  2. 커널모드 동기화 :
    1. 개요 : 정확히는 커널 오브젝트를 이용한 스레드 동기화. 스레드를 동기화 하기 위해 커널 오브젝트 등을 어떻게 사용할것인가 에 대한 설명을 적을 예정.
    2. 시그널 / 논 시그널 : 시그널 상태 - 사용 가능 상태, 논 시그널 - 대기 상태 (사용중인 상태)
    3. 대기함수 : 대기함수 호출시 인자로 전달된 커널 오브젝트가 시그널 상태가 될때까지 '대기함수를 호출한 스레드'를 대기상태로 유지시킴.
      대기함수 호출시 커널 오브젝트가 시그널 상태면 대기상태로 전환되지 않음.
    4. 대기 함수 사용시 'dwMilliseconds'와 같은 대기시간 인자에 'INFINITE'를 전달 할 수 있음. 이때에는 스레드가 영원히 블로킹 되지 않도록 주의가 필요.
    5. '성공적인 호출', '성공적인 대기의 부가적인 영향' : 성공적인 호출을 통해 오브젝트의 상태가 변경 시 '성공적인 대기의 부가적인 영향' 이라고 칭함. (책에선 그러더라구요)
      '성공적인 호출'은 매개변수로 전달된 커널 오브젝트가 정상적으로 시그널 상태가 된 것을 의미.
  3. 커널 오브젝트 리스트 :
    1. 이벤트 커널 오브젝트 (이벤트 기반 동기화) : 이벤트 = '작업이 완료되었음을 알림'. 수동 리셋 이벤트 / 자동 리셋 이벤트가 존재.
      수동 리셋 이벤트 : 시그널 상태 시 대기중인 모든 스레드는 동시에 스케줄 가능한 상태가 됨
      자동 리셋 이벤트 : 시그널 상태 시 대기중인 오브젝트 중 하나만이 스케쥴 가능한 상태가 됨
    2. 대기 타이머 커널 오브젝트 (Waitable Timer) : 특정 시간 / 일정 시간 간격을 두고 시그널 상태가 되는 커널 오브젝트.
      특정 시간 / 간격에 맞춰서 작업을 수행해야하는 경우 사용.
      대기 타이머는 항상 논 시그널 상태로 생성됨.
      유저 타이머 (SetTimer를 사용)와의 차이점 - 대기 타이머는 커널 오브젝트임으로 다수의 스레드에서 공유될 수 있고 좀 더 보안에 안정적임.
    3. 세마포어 커널 오브젝트 : 리소스의 개수를 고려해야 하는 상황에서 주로 사용됨.
      최대 리소스 카운트, 현재 리소스 카운트를 저장하고 사용함.
      대기함수가 세마포어를 전달받을 시 현재 리소스 카운트 값을 확인하고 0보다 크면 값을 1 감소시키고 대기함수를 호출한 스레드를 스케줄 가능상태로 만듬. 
      현재 리소스 카운트가 0이면 (=세마포어가 논 시그널이면) 호출한 스레드를 대기상태로 유지시킴.

      작동 규칙 : 
      1. 현재 리소스 카운트가 0보다 크면 시그널
      2. 현재 리소스 카운트가 0이면 논시그널
      3. 현재 리소스 카운트는 0 미만이 될 수 없음
      4. 현재 리소스 카운트는 최대 리소스 카운트보다 커질 수 없음
    4. 뮤텍스 커널 오브젝트 (Mutual Exclusion ; 상호배제) : 크리티컬 섹션과 유사.

      작동 규칙 :
      1. 스레드 ID가 0 (유효하지 않은 스레드 ID)일 시 : 시그널 상태 ; 어떠한 스레드도 뮤텍스를 소지하지 않음
      2. 스레드 ID가 0이 아닌 경우 : 논 시그널 상태 ; 특정 스레드에 의해 소지중 
      3. (그 외 특수한 경우 규칙 위반 가능)
        1. 논시그널 상태에서도 스레드가 뮤텍스를 다시 소지가능
        2. 뮤텍스를 소지한 스레드가 소유권을 해지하지 않고 종료되는 경우, '버림' 처리 되어 소유권을 강제로 해제시킴

그냥 혼자 책읽고 하기에는 내용을 자꾸 빼먹는거 같아서 필기도 할겸...

 

아래 내용은 'Windows via C/C++'을 기반으로 하고 있습니다.

 

* 틀린거 많으니 교차검증 꼭 하세요 *


  1. 커널 오브젝트 이론
    1. 커널 오브젝트는 OS가 제공/사용하는 커널레벨의 기능을 추상화 시킨 오브젝트 타입이다.
      커널에 의해 할당된 메모리 블럭들로, 이 메모리 블럭들은 커널 오브젝트에 대한 세부 정보드를 저장하고 있으며 커널에 의해서만 접근이 가능한 구조체로 구성되어 있다.
    2. 커널 오브젝트의 데이터 구조체는 커널에서 접근이 가능하기 때문에 애플리케이션 레벨 (유저레벨)에서 해당 정보를 직접 변경하는것은 불가능. 
    3. 커널 오브젝트 사용은 각각의 호출 함수를 통해 핸들 (HANDLE 타입 변수들)을 얻어 조작이 가능하다.
    4. 커널 오브젝트는 프로세스에서 소유하는것이 아닌 커널에서 소유함. 즉, 특정 프로세스에서 커널 오브젝트 생성을 지시하였어도 해당 프로세스가 소멸시 커널 오브젝트도 같이 소멸한다는 보장은 할 수 없음.

 

 

 

 

#define _CRTDBG_MAP_ALLOC
#include <cstdlib>
#include <crtdbg.h>

 

그리고 메인 함수에 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 넣어줄것.

 

 

p.s : 특정 메모리 위치 찍어내기 : _CrtSetBreakAlloc(번호) 

+ Recent posts