그동안 언리얼 엔진과 C++을 통해 객체 지향의 기초를 다졌다면, 오늘부터는 유니티 엔진과 C#을 활용한 게임 개발 공부를 시작합니다. 유니티 개발의 가장 기본이 되는 유니티 생명주기(Unity LifeCycle)에 대해 정리해 보겠습니다. 1) 유니티 생명주기(LifeCycle)란? 유니티의 모든 스크립트는 MonoBehaviour 클래스를 상속받으며,...
오늘은 프로그램의 논리적 흐름을 제어하는 가장 기초적이면서도 중요한 요소인 조건문과 반복문에 대해 정리해 보겠습니다. 1) 조건문(If)과 방어 코드의 중요성 조건문은 주어진 조건식의 결과가 참(True)인지 거짓(False)인지에 따라 실행할 코드 블록을 결정하는
2일차에서 반복 횟수가 명확할 때 사용하는 for문에 대해 학습했다면, 오늘은 조건에 따라 반복 여부를 결정하는 while문과 do~while문에 대해 정리해 보겠습니다. 1) while while문은 소괄호 안의 조건식이 참(True)인 동안 중괄호 안의 코드를 무한히 반복합니다. for문은 반복 횟수를 미리 지정하고 시작하는 경우가 많지만, while...
오늘은 동일한 타입의 데이터를 효율적으로 묶어서 관리할 수 있는 배열(Array)에 대해 정리해 보겠습니다. 유니티 개발에서 인벤토리 슬롯이나 스테이지 정보처럼 고정된 데이터를 다룰 때 필수적인 개념입니다. 1) 배열(Array)의 개념과 특징 배열은 메모리 공간에 데이터를 연속적으로 나열하여 고정시켜 놓고 사용하는 자료구조입니다. 가장 큰 특징은 한 번...
오늘은 배열 내 데이터의 위치를 바꾸는 스왑(Swap)과 전체적인 순서를 무작위로 뒤섞는 셔플(Shuffle) 알고리즘에 대해 정리해 보겠습니다. 1. Swap 스왑은 두 변수에 담긴 값을 서로 교체하는 알고리즘입니다. 프로그래밍에서 두 값을 직접 바꾸는 것은 불가능하기 때문에, 데이터를 잠시 보관할 임시 변수(Temp)를 활용하는 것이 핵심입니다. ...

배열의 가장 큰 단점은 고정된 크기입니다. 물론 늘리거나 줄일 수는 있지만 이를 로직으로 처리하는 과정은 불편함이 동반합니다. 오늘은 고정된 크기 배열을 해결하는 동적 배열인 리스트(List)에 대해 정리해 보겠습니다. 1. List 리스트는 배열과 비슷하게 데이터를 순차적으로 저장하는 자료구조이지만, 생성할 때 크기를 미리 정하지 않아도 되는 동적 배...
C# 개발 공부 - 7일차 오늘은 데이터가 들어오고 나가는 순서가 정해져 있는 자료구조인 스택(Stack)과 큐(Queue)에 대해 정리해 보겠습니다. 1) Stack 스택은 데이터를 차곡차곡 쌓아 올리는 형태로 가장 마지막에 들어온 데이터가 가장 먼저 나가는 LIFO(Last In First Out, 후입선출) 구조를 가집니다. 게임 개발에서의 사...

오늘은 데이터를 정의하는 방식인 구조체(Struct)와 클래스(Class)의 차이와 이 두가지가 메모리에서 어떻게 다루어지는지에 대해 정리해 보겠습니다. 1) Struct(구조체) 구조체는 여러 개의 변수를 하나로 묶어 새로운 데이터 타입을 만드는 사용자 정의 타입입니다. 클래스와 매우 흡사한 형태를 가지지만, 본질적으로는 값 타입(Value Type)...
오늘은 게임의 상태를 체계적으로 관리하는 방식으로 사용되는 설계 방식 상태머신(StateMachine)과 이를 효율적으로 구현하기 위한 Switch구문에 대해 정리해보겠습니다. 1) StateMachine 상태머신은 객체가 가질 수 있는 여러 가지 상태를 정의하고, 한 번에 오직 하나의 상태에만 머물게 하며 특정 조건에 따라 상태를 전환하는 설계 방식입니...
오늘은 유니티에서 사용하는 클래스의 두 가지 종류와 객체 지향의 캡슐화에 대해 정리해 보겠습니다. 1) Class 종류 유니티에서는 클래스가 크게 두 가지 형태로 구분되어 사용됩니다. 일반 C# 클래스 (Plain Class) new 키워드로 직접 인스턴스를 만들 수 있습니다. 데이터나 로직의 묶음을 관리하기에 좋으며, 예를 들어 플레이어의 능력치 데...
오늘은 프로그램의 유연성과 확장성을 극대화하는 다형성(Polymorphism)과 인터페이스(Interface)에 대해 정리해 보겠습니다. 1) 다형성 (Polymorphism) 다형성은 하나의 객체가 여러 가지 형태를 가질 수 있는 능력을 의미합니다. 객체 지향 프로그래밍의 핵심 중 하나로, 부모 클래스 타입의 변수로 자식 클래스 객체를 참조할 수 있는...
오늘은 객체 지향의 상속(Inheritance)과 다양한 재정의 기법들에 대해 정리해 보겠습니다. 1) 상속 (Inheritance) 상속은 (부모 클래스가 가지고 있는 멤버와 기능을 자식 클래스가 그대로 물려받는 것을 의미합니다. 이를 통해 코드의 재사용성을 높이고 클래스 간의 계층 구조를 형성할 수 있습니다. 부모 클래스를 기반으로 자식 클래스에서...

지난번 C# 개발 공부의 상속을 끝으로 1차적인 C# 개발 공부를 마무리하였습니다. 이후부터는 Unity Engine을 학습함과 동시에 C#에서 배웠던 개념을 복습하거나 응용하는 내용을 정리해보겠습니다. 1) Sprite Renderer Sprite Renderer는 유니티에서 2D 이미지를 화면에 그려주는 역할을 하는 컴포넌트입니다. 프로젝트 뷰에 있는...
오늘은 프레임에 따른 로직 실행의 차이와 유니티 물리 시스템의 두 축인 Collision, Trigger의 차이점에 대해 정리해 보겠습니다. 1) Update()와 FixedUpdate() 유니티에는 매 프레임 실행되는 함수가 여러 종류 있습니다. 그중 가장 자주 쓰이는 두 함수와 그 차이는 다음과 같습니다. Update() 개념: 화면이 한 번 그려질...

오늘은 플레이어가 동작하는 다양한 키 동작을 게임에 전달하는 입력 시스템에 대해 정리해보겠습니다. 1) InputAction InputAction은 어떤 장치(키보드, 마우스, 패드 등)에서 입력이 들어오든 이를 하나의 액션으로 관리하는 단위입니다. (ex. jump, 플레이어 이동) 기존의 Legacy Input 방식인 Input.GetKey는 특정 ...

오늘은 데이터를 더 효율적으로 관리하고 시각적으로 디버깅하며 게임의 흐름(시간)을 제어하는 핵심 기술들을 정리해보겠습니다. 1) 비트 연산자 비트 연산자는 데이터를 비트(0과 1) 단위로 직접 조작하는 연산자입니다. 컴퓨터가 가장 빠르게 처리할 수 있는 연산 방식이며, 주로 여러 상태를 하나의 정수 변수에 담는 플래그(Flag) 처리나 레이어 마스크(La...
오늘은 발사체(Projectile)를 만들 때 필수적인 회전 연산에 대해 정리해 보겠습니다. 1) Mathf.Atan2 Mathf.Atan2는 두 지점 사이의 상대적인 위치(y, x)를 입력받아 그 방향이 나타내는 각도를 라디안(Radian) 단위로 반환하는 함수입니다. 일반적인 탄젠트 역함수(Atan)와 달리, x값이 0인 경우나 사분면의 위치를 스스로...
오늘은 삼각함수를 통한 발사체의 궤적이나 물체의 움직임을 더 다양하게 조절하는 방법과 방대한 데이터를 효율적으로 관리할 수 있는 Dictionary에 대해 정리해보겠습니다. 1) Mathf.Cos Mathf.Cos는 입력받은 각도(라디안)에 대한 코사인 값을 반환하는 함수입니다. 단위 원에서 X축의 좌표값을 의미하며, -1에서 1 사이의 값을 반복해서 출...

오늘은 플레이어와 게임이 소통하는 창구인 UI(User Interface) 시스템에 대해 정리해 보겠습니다. 1) UGUI UGUI(Unity Graphical User Interface)는 유니티에서 기본으로 제공하는 컴포넌트 기반의 UI 시스템입니다. 게임 화면 위에 체력 바, 버튼, 텍스트 등을 배치하여 정보를 전달하고 입력을 받는 역할을 합니다. ...
오늘은 out 키워드와 이벤트 시스템에 대하여 정리해보겠습니다. 1) out parameter out 키워드는 메소드에서 두 개 이상의 값을 반환하고 싶을 때 사용하는 매개변수 수식어입니다. 일반적인 return은 하나의 값만 돌려줄 수 있지만, out을 사용하면 호출한 곳으로 여러 데이터를 전달할 수 있습니다. out 파라미터는 초기화를 필수적으로 진...
오늘은 작성된 코드의 가독성을 높이는 방법인 코드 리팩토링(Code Refactoring)에 대해 정리해 보겠습니다. 1) Code Refactoring 리팩토링은 소프트웨어의 겉으로 드러나는 기능(동작)은 바꾸지 않으면서, 내부적인 코드 구조를 개선하여 가독성을 높이고 복잡도를 낮추는 행위를 말합니다. 즉, 똑같이 동작하는 코드를 더 보기 쉽게 다듬는 ...
오늘은 SOLID원칙과 이를 활용한 FSM기법에 대해 정리해 보겠습니다. 1) SOLID SOLID는 좋은 소프트웨어 설계를 위해 지켜야 할 객체 지향 설계의 5가지 원칙을 의미하며 다음과 같습니다. 단일 책임 원칙 (SRP) 하나의 클래스는 단 하나의 책임(기능)만 가져야 합니다. 예를 들어 플레이어 컨트롤러가 이동 로직과 사운드 재생, UI 업데이트...

오늘은 게임의 애니메이션 시스템에 있어 핵심 요소에 대해 정리해보겠습니다. 1) 애니메이터 (Animator) 애니메이터는 게임 오브젝트의 애니메이션을 제어하는 상태 머신입니다. 어떤 애니메이션 클립을 언제, 어떤 조건에서 재생할지 결정하는 역할을 담당합니다. 유니티의 애니메이터 창에서 상태(State)를 만들고 전이(Transition) 화살표를 연결...

오늘은 애니메이션을 직접 구성하는 방법과 캐릭터의 움직임을 더 자연스럽게 만들어주는 방법에 대해 정리해보겠습니다. 1) 애니메이션 구성 애니메이션을 구성하기 위해서는 애니메이터 컨트롤러의 내부 구성을 이해해야합니다. 내용은 다음과 같습니다. 파라미터 구성: 좌측 상단에 위치한 파라미터는 스크립트와 애니메이터 사이를 연결하는 변수 역할을 수행합니다. 예를...
오늘부터 15일간 2D 기반의 게임 개발을 주제로 개인 프로젝트를 진행합니다. 제가 기획하는 프로젝트는 로그라이크 덱빌딩 장르인 Balatro를 모작하는 것을 주제로 선정하였습니다. * 왜 Balatro? Balatro(발라트로) 모작을 하게된 이유로 부트캠프에 참여하면서 들었던 얘기중 카드 게임이 기본기를 다지는데 좋은 소재라는 얘기를 들었습니다. 지...
오늘은 프로젝트의 기본구조를 설정하고 1차 구현 목표로 설정한 카드 생성 ~ 게임 승리/패배 판정 흐름에서 카드 생성, 셔플, 드로우, 선택, 버리기 기능 구현에 대한 내용을 정리해보겠습니다. 구현 흐름 먼저, 카드 생성 - 셔플 - 드로우의 경우 다음의 구현 흐름으로 기획하였습니다. 다음, Hand 드로우, 카드 선택, 버리기 기능은 다음과 같은 흐...
오늘은 선택한 카드를 기반으로 족보를 확인하고 Chip과 Mult를 활용한 카드 계산 구현에 대한 내용을 정리해보겠습니다. 구현 흐름 먼저 카드 계산에 대한 흐름은 다음과 같이 기획하였습니다. 다음 카드 계산에 있어 중요한 선택한 카드 기반 족보를 판정할 기준을 다음과 같이 기획하였습니다. 구현 코드 기획한 흐름을 기반으로 작성한 코드는 다음과 같습니...
오늘은 Balatro의 핵심 재미 요소. JokerCard에 대한 구현과 Jokercard를 통한 카드계산 기능 구현에 대한 내용을 정리해보겠습니다. 구현 흐름 조커 카드를 생성하고 카드 계산을 위해 다음과 같은 흐름으로 기획하였습니다. 구현 코드 JokerCard, JokerSlot, JokerCalculator의 핵심 구현 코드는 다음과 같이 구현해...
오늘은 게임의 전반적인 정보를 저장하는 Manager에 대한 구현 내용을 정리해보겠습니다. 구현 흐름 플레이에 필요한 정보를 담당하는 Manager에는 다음과 같은 내용으로 기획하였습니다. 구현 코드 트러블슈팅 데이터 일관성 오류 상황: RoundManager의 경우 데이터 일관성을 유지함과 동시에 전역에서 하나의 정보를 기준으로 처리해야하기 때문...
오늘은 Balatro의 JokerCard를 구매할 수 있는 상점을 구현한 내용을 정리해보겠습니다. 구현 흐름 상점은 다음과 같은 내용으로 기획하였습니다. 구현 코드 상점은 다음과 같이 기능을 담당하는 ShopManager와 UI를 담당하는 ShopUI로 나누어 코드를 구현하였습니다. 트러블 슈팅 상황 동일한 JokerCard가 상점에 계속 노출된다....
오늘은 카드 족보를 강화하는 카드 행성카드에 대한 구현과 행성카드 사용 기반 포커 족보 강화에 대한 구현 내용을 정리해보겠습니다. 기획 흐름 행성 카드는 다음과 같이 기획하였습니다. 구현 코드 행성 카드는 PlanetCard에서 카드 생성 및 족보 강화를 진행, ConsumableSlot, ShopUI, ShopManager에서 상점에 표시 및 구매, ...
오늘은 게임 내 구현 목표상의 마지막 파트인 바우처카드 구현과 바우처 카드 기반 게임 내 자원 강화 시스템에 대하여 구현한 내용을 정리해보겠습니다. 기획 흐름 바우처카드는 다음의 흐름으로 기획하였습니다. 구현 코드 바우처카드는 다음과 같이 코드를 구현하였습니다. 이번 바우처 카드의 효과에 따른 RoundManager의 정보 변경에 있어 함수를 호출하는...

오늘은 이전까지 구현한 코드를 기반으로 실제 게임에 보여질 UI를 구성하는 시간을 가져보겠습니다. 카드들에서 공통적으로 진행되는 Sprite설정 및 카드 선택에 따른 위치 변경에 대하여 주로 구현하였으며, 일부 애니메이션 연출에 대해서는 코드 기반의 애니메이션 연출을 할 수 있는 DOTween을 이용하였습니다. 씬 구현 먼저 씬과 씬별 역할은 다음과 ...

코드와 UI구현은 최종적으로 완료되었습니다. 테스트를 통해서 실제 게임 동작에 따른 오류를 고쳐나가는 작업도 거의 완료되었습니다. 하지만, 같이 교육을 받고 있는 팀원들간의 완성된 게임 공유 및 테스트를 통해 직접 테스트 했을 때 발견하지 못했던 여러 이슈가 나타났습니다. 그래서 오늘은 어떤 오류가 발생했는지, 그리고 어떻게 해결했는지에 대해서 정리해보겠습...
오늘은 Balatro 모작 최종 개발에 따른 내용정리를 비롯하여 프로젝트에 대한 회고를 작성하도록 하겠습니다. 1. 프로젝트 개요 개발 기간: 26. 4. 8 ~ 26. 4. 27 개발 환경 Unity(6000.3.9f1), C 주요 라이브러리: DOTween(애니메
2D 게임 개발 프로젝트를 마치고 오늘부터는 3D기반의 게임 개발에 필요한 학습을 진행합니다. 오늘 배운 내용은 게임의 눈 역할을 하는 카메라에 대해 학습한 내용을 정리해보겠습니다. 1) Camera 게임 세계에는 수많은 3D 메쉬와 정점들을 배치하지만 그 모든 것들을 다 그리고 플레이어에게 제공하지않습니다. 카메라를 통해 플레이어에게 제공되는 시야 공간...

오늘은 객체의 방향을 변화시키는 행위를 의미하는 회전의 개념에 대해 정리해보겠습니다. 1) Euler Angles 오일러각은 가장 흔히 사용하는 회전 방식입니다. X, Y, Z 축을 기준으로 몇도를 돌릴지 결정합니다. 일상생활에 사용되는 만큼 이해하기 쉽고 직관적입니다. 인스펙터 창에서 직접 숫자를 입력해 조작하기가 쉽습니다. 비행기의 회전으로 비유...
오늘은 3D 그래픽에 대하여 학습한 내용을 정리해 보겠습니다. 1) Mesh 메시는 3D 공간에서 점, 선, 면으로 구성된 물체의 외형 데이터를 말합니다. 메시는 다음과 같이 나눌 수 있습니다. 정적 메시 (Static Mesh): 움직임이 없는 고정된 모델로 주로 건물, 바위, 나무 등 지형지물을 만들 때 사용합니다. 스켈레탈 메시 (Skeleta...
수많은 오브젝트가 화면에 생성되었다 삭제되면 불필요한 G.C가 발생합니다. 오늘은 다량의 오브젝트에 있어서 게임의 퍼포먼스를 유지하기 위한 최적화 기법인 오브젝트 풀링(Object Pooling)에 대해 정리해보겠습니다. 1) Object Pooling? 오브젝트 풀링은 오브젝트를 담아두는 Pool을 미리 만들어두는 기법입니다. 새로운 오브젝트가 필요할...

오늘은 시간의 흐름이 있는 절차를 순서대로 표현할 때 사용하는 코루틴에 대해 정리해보겠습니다. Coroutine? 일반적인 함수는 한 번 호출되면 끝날 때까지 제어할 수 없습니다. 하지만 코루틴은 실행을 일시정지하고 나중에 정지된 시점부터 다시 실행할 수 있는 함수입니다. 코루틴을 사용하기 위해서는 다음의 문법을 이해하고 있어야합니다. IEnumera...
오늘은 Unity에서 제공하는 보이지 않는 레이저를 쏘아 무엇이 있는지를 확인할 수 있는 기능인 Raycast에 대해 정리해보겠습니다. Raycast? Raycast는 광선이 발사되는 시작점(Origin)에서 발사되는 벡터 방향(Direction)으로 얼마만큼 나아가는지(Distance)를 설정하여 보이지 않는 광선을 발사하여 광선에 맞은 정보(hit)를...
지난번에 Raycast에 대한 기본을 정리하였습니다. 오늘은 단순한 선이 아닌 두께가 있는 도형을 쏘거나 범위내에 존재하는 Object를 판별하는 개념에 대하여 정리해보겠습니다. 1. Shapecast Shapecast는 선이 아닌, 도형을 특정 방향으로 쏘아 경로상의 충돌을 찾는 방식을 의미합니다. 캡슐 형태의 캐릭터가 이동시 장애물을 미리 감지하거나...
오늘은 객체의 상태에서 행위와 공통 데이터를 분리하여 메모리를 최적화하는 아키텍처 패턴인 ScriptableObject에 대해 정리해보겠습니다. MonoBehaviour의 한계 기존의 모노비헤이어의 방식으로 데이터를 관리할 때 다음의 문제점이 존재하빈다. 메모리 낭비 다수의 적을 생성할 때, 그만큼의 프리팹이 동일한 수치를 메모리에 중복해서 생성하기 때문...

오늘은 게임의 메모리를 아끼고 빌드 용량을 최적화하기 위해 사용하는 자원 관리 시스템 Addressable에 대해 정리해보겠습니다. Addressable 어드레서블은 에셋의 위치에 관계없이 에셋에 부여된 고유 주소를 갖고 비동기적으로 로드 및 해제할 수 있게 해주는 시스템입니다. 기존의 [SerializeField] 방식은 연결된 모든 프리팹과 SO 데...