반응형

C#과 유니티로 만드는 MMORPG 게임 개발 시리즈 210

Part 3-6-2. 애니메이션 : State 패턴, State Machine

Animation(애니메이션) State 디자인 패턴 bool isFalling; bool isJumping; bool isSkillCasting; bool isSkillChanneling; if(isJumping) { } else { if(isSkillChanneling && isFalling) { } else { if(isSkillCasting) { } } } 이런식으로 bool타입의 상태 flag 변수를 여러개 사용하면 너무 복잡하다. if - else문이 너무 많아진다. 상태 flag 변수가 적은 갯수라면 괜찮지만 규모가 큰 게임일 수록 많이 필요하기 때문에 적합하지 않다. 해결 방법 👉 State 패턴 사용하기! using System.Collections; using System.Collect..

Part 3-6-1. 애니메이션 : 기초, 블렌딩

Animation(애니메이션) 휴머노이드 애니메이션 “Unity Model”을 선택하면 유니티에서 기본으로 지원해주는 모델에게 애니메이션을 적용시킨다. 또한 Humanoid 타입의 애니메이션 파일은 Humanoid 뼈대를 가진 모델이라면 어떤 애니메이션이든지 그 모델에 입힐 수 있다. 애니메이션의 위와같은 버튼을 누르면 애니메이션을 입힐 모델을 선택할 수 있다. 원하는 모델을 에셋에서 드래그 앤 드롭 해서 애니메이션에 입힐 수도 있다. Animator 컴포넌트 Controller 애니메이터 컨트롤러는 애니메이션을 재생 시키는 상태 머신을 정의할 수 있다. 애니메이터 컨트롤러에 할당하면 애니메이터 컨트롤러에서 정의한대로 애니메이션을 재생시킨다. Avatar 애니메이션의 뼈대가 될 아바타. 애니메이터가 Hu..

Part 3-5-3. 카메라 : 카메라가 벽에 막힐시, 벽 앞으로 카메라 이동시키기

카메라 플레이어를 따라가던 카메라가 벽에 가려지면, 벽 앞으로 카메라 이동시키기 📜CameraController.cs void LateUpdate() { if (_mode == Define.CameraMode.QuaterView) { RaycastHit hit; if(Physics.Raycast(_player.transform.position, _delta, out hit, _delta.magnitude, LayerMask.GetMask("Wall"))) { float dist = (hit.point - _player.transform.position).magnitude * 0.8f; transform.position = _player.transform.position + _delta.normalized..

Part 3-5-2. 카메라 : 클릭한 곳으로 플레이어 이동하기

카메라 롤이나 스타처럼 클릭한 곳으로 플레이어와 카메라가 따라가게 하기. 바닥에 마우스를 클릭하면 클릭한 곳으로 플레이어가 자동으로, 스스로 이동하게 한다. 방법 소개 1️⃣ 카메라를 플레이어의 자식으로 넣기 단점 👉 플레이어가 회전하면 카메라도 같이 회전한다. 그래서 휙휙 돌아서 너무 어지럽다. 2️⃣ 부모-자식 관계가 아닌 별개로 두되, 카메라가 플레이어와 적정 Vector3 값을 유지한체, 플레이어를 바라보며 따라다니게 하기 카메라의 위치는 (플레이어와의 위치 + 카메라와 플레이어의 적당한 Vector3 값)로 업데이트 하고, 카메라는 LookAt 함수를 이용하여 플레이어의 위치를 바라보게 회전한다. 플레이어가 바라보는 방향으로 회전하는 것이 아닌, 카메라가 그냥 플레이어의 위치를 바라보게 회전하는..

Part 3-5-1. 카메라 : 카메라가 플레이어를 따라다니게 만들기

카메라 카메라가 플레이어를 따라다니게 만들기 방법 소개 1️⃣ 카메라를 플레이어의 자식으로 넣기 단점 👉 플레이어가 회전하면 카메라도 같이 회전한다. 그래서 휙휙 돌아서 너무 어지럽다. 2️⃣ 부모-자식 관계가 아닌 별개로 두되, 카메라가 플레이어와 적정 Vector3 값을 유지한체, 플레이어를 바라보며 따라다니게 하기 카메라의 위치는 (플레이어와의 위치 + 카메라와 플레이어의 적당한 Vector3 값)로 업데이트 하고, 카메라는 LookAt 함수를 이용하여 플레이어의 위치를 바라보게 회전한다. 플레이어가 바라보는 방향으로 회전하는 것이 아닌, 카메라가 그냥 플레이어의 위치를 바라보게 회전하는 것이다. 📜Define.cs using System.Collections; using System.Collect..

Part 3-4-2. Raycast, LayerMask, Tag, 투영의 개념

Raycast 광선을 쏴서 충돌되는 물체가 있는지 없는지를 검사하는 것 예를 들어 1. 게임 속 물체를 클릭한다는 것은 클릭한 화면의 위치로부터, 즉 카메라의 위치로부터 레이저(Raycast)를 쏴서 닿은 물체를 활성화시키는 것과 같다. 2. 3인칭 카메라에서 플레이어를 향해 Raycast를 쐈을 때 장애물이 있다면 플레이어를 가리지 않고 제대로 찍을 수 있도록 카메라 위치를 장애물을 넘어가는 곳으로 이동시키는 식으로 구현할 수 도 있다. 3. 롤이나 스타크래프트처럼 마우스로 화면상에 찍은 위치에서 카메라가 Raycast를 월드 좌표로서 쏴서 그 곳으로 캐릭터를 이동시키게도 할 수 있다. 하나만 부딪치면 끝난다. 하나 충돌되면 더 이상 관통하지 않는다. void Update() { RaycastHit h..

Part 3-4-1. Collider, Collision, Trigger

Collider Collider 컴포넌트를 붙였다고 해서 관통이 안된다거나 튕겨진다던가 하는 처리 등은 할 수는 없다. 그러한 처리등은 Rigidbody나 NavMeshAgent 같은 어떤 물리적인 처리를 해주는 컴포넌트들이 하는 일이다. Collider는 어디까지나 그냥 참고사항일 뿐이다. 위와 같이 Mesh 는 굉장히 복잡하게 이루어져 있다. 무수한 삼각형들의 조합으로 이루어져 있기 때문에 충돌 기준을 이 Mesh 기준으로 잡으면 어마무시한 연산량이 필요할 것이다. 따라서 위와 같이 Box 모양인 Sphere 혹은 Capsule 모양의 Collider 를 Mesh를 감싸도록 붙여서 이렇게 단순하게 생긴 것으로 충돌 처리를 대신한다! Collider 영역 안에 오브젝트가 닿거나 들어오면 충돌한 것으로 ..

Part 3-3-1. Prefab (프리팹), Resource Manager

Prefab (프리팹) 프리팹 정의와 생성 👉 오브젝트를 에셋 파일로 만들어 두는 것을 Prefab 이라고 한다. 만들어 둔 프리팹을 CLone 화 하여 씬에 실존하는 오브젝트로 찍어낼 수 있다. 프리팹을 이용하여 게임 도중에도 실시간으로 오브젝트를 씬 상에서 실존하도록 찍어내어 생성할 수 있고, 프리팹 하나로 수 많은 동일한 오브젝트들을 동시에 생성할 수도 있다. Class(프리팹)를 만들어 두고 이것을 객체 인스턴스(오브젝트)로 찍어내는 것과 같다. 프리팹은 오브젝트와 다르게 게임 상에 실존하는게 아니라 오브젝트를 찍어내는 틀이라고 생각하면 된다. 프리팹 만드는 방법 그냥 프리팹화 하려는 오브젝트를 📂Assets 에 드래그 앤 드롭 하면 된다. 프리팹을 Scene에 오브젝트로서 찍어내기 (Clone ..

Part 3-2-1. Transform (트랜스폼), InputManager

[Scale] 오브젝트의 크기. 확대/축소 할 수 있는 기능이다. 지구와 성 등 보다 큰 모델을 필요하다고 가정하면, 모델을 만들 때 처음부터 거대한 모델을 만들 필요 없이 작게 만들어 유니티에 와서 Scale을 통해 크기를 늘리면 된다. [Position] 오브젝트의 위치. 이동과 관련되어 있는 기능이다. 거리 = 시간 * 속력 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { [SerializeField] private float _speed = 10.0f; void Update() { if (Input.GetKey(KeyCo..

Part 3-1-1. 싱글톤

게임 매니저 👉 전역으로 선언하여 게임 전체를 관리하는 스크립트! 게임 매니저는 '컴포넌트'이므로 딱히 어떠한 오브젝트에 꼭 붙어야 하는 이유는 없지만, 모노비헤이비어를 이용하기 위해 실체는 없지만 Scene에 존재하긴 하는 빈 오브젝트를 만들어서 매니저 스크립트를 컴포넌트로서 붙이고 사용하는 것을 권장한다. 따라서 매니저 스크립트를 붙일 용도의 빈 오브젝트를 만들자. 싱글톤 게임 매니저 스크립트가 붙은 오브젝트를 가져오는 것. 현재 “@Managers” 라는 빈 오브젝트에 게임 매니저로 쓸 Managers 라는 C# 스크립트를 붙여준 상태이다. Player.cs using System.Collections; using System.Collections.Generic; using UnityEngine; ..

Part 2-6-1. A* 길찾기 알고리즘

A* 길찾기 알고리즘 A* 길찾기 알고리즘과 다익스트라 알고리즘 비교 [다익스트라] 1. 해당 지점에서 갈 수 있는 모든 경로에 대한 최단 거리를 찾는다. (비효율적) 따라서 시작 지점만 알면 된다. 목적지를 주진 않는다. 다익스트라를 목적지 찾으면 종료하게끔 개선할 수도 있지만 그래도 아쉽다. 매번 모든 지점마다 갈 수 있는 모든 경로에 대한 최단 거리를 찾아 비교하기 때문이다. 2. 예약된 정점들 중 최고의 정점을 선택할 땐 최단 거리 경로를 유지할 수 있는 정점을 선택한다. [A*] 1. 모든 경로를 다 찾지 않는다. (시작 지점, 끝 지점 목적지. 이렇게 두 개가 주어진다. 목적지를 알고 있다.) 2. 예약된 정점들 중 최고의 정점을 선택할 땐 1️⃣ 최단 거리 경로를 유지할 수 있는 정점도 고려..

Part 2-5-2. 트리 : 힙 트리, 우선순위 큐

힙 이진 트리 모든 노드들이 자식 노드를 최대 2 개까지만 가지는 트리 이진 트리의 종류 1. 이진 검색 트리 (Binary Search Tree) 항상 왼쪽 자식은 나보다 작고 오른쪽 자식은 나보다 크다. 2. 힙 트리 (Heap Tree) Max Heap Tree : 항상 부모가 자식보다 크다. 따라서 루트는 최대값이다. Min Heap Tree : 항상 부모가 자식보다 작다. 따라서 루트는 최소값이다. [이진 트리] 다음과 같은 조건이 적용된 이진트리 1. 왼쪽을 타고 가면 현재 값보다 작다. 👉 왼쪽 자식 노드는 부모 노드보다 작아야 한다. 루트를 기준으로 왼쪽 서브트리 노드의 데이터들은 전부 루트보다 작은 값을 가진다. 2. 오른쪽을 타고 가면 현재 값보다 크다. 👉 오른쪽 자식 노드는 부모 노..

Part 2-5-1. 트리 : 트리 이론과 구현

트리 [트리 이론] 트리 👉 계층적 구조를 갖는 데이터를 위한 자료 구조 ex) 회사 조직도, 노드(Node) : 데이터 표현 루트(Root) 노드는 트리를 상징하며, 부모가 없다. 즉 최상위 조상이 되는 트리의 첫 노드. 잎(Leaf) 노드는 자식이 없는, 트리의 말단 노드들을 뜻한다. 간선(Edge) : 노드의 계층 구조를 표현하기 위해 사용 이름 그대로 나무와 같다. 뻗어 나가는 구조. 트리도 그래프의 일종이라고 볼 수 있다. 단, 제한적인 모양의 그래프라고 생각할 수 있다. 또한 트리는 사이클이 있어선 안된다. 👉 한 쪽 방향으로만 뻗어야 한다. 각 노드의 부모는 딱 하나만 있어야 한다. 트리는 재귀적인 속성을 가진다. 따라서 트리에서 일부분을 떼보면 그 부분도 트리다.(서브 트리) 트리 구현 트..

Part 2-4-5. 그래프 : 다익스트라 최단 경로 알고리즘

다익스트라 최단 경로 알고리즘 최소 비용으로 모든 정점을 방문한다. 0 방문 예약 👉 1 (15), 3 (35) 0 을 지나 1 으로 온다면 1의 가중치는 15 0 을 지나 3 으로 온다면 3의 가중치는 35 15 = closet) continue; // 지금 시점까지 발견한 가장 좋은 후보 closet = distance[i]; now = i; } distance가 Int32.MaxValue 이 아니면 3️⃣ 과정에서 현재 예약 되어 있거나, 혹은 예약이 예전에 됐던적이 있는 정점이다. 최소값 찾기 알고리즘처럼 closet에 해당 시점까지의 최소값을 저장해 나가고 더 작은 distance를 가진 정점을 찾으면 해당 값으로 업데이트 한다. now에도 그때 그때 시점에서의 최단 거리를 가진 정점을 저장해두..

Part 2-4-4. 그래프 : BFS(너비 우선 탐색)

BFS(너비 우선 탐색) Queue 큐를 이용하여 가까운 순서대로 방문한다. 출발 정점을 기준으로 가까운 순서대로 차례 차례 방문한다. 예를 들어 순회을 0 정점에서 시작한다면 0 정점에서 거리 1 (간선 1 개를 타야 갈 수 있는) 👉 1, 3 0 정점에서 거리 2 (간선 2 개를 타야 갈 수 있는) 👉 2, 4 0 정점에서 거리 3 (간선 3 개를 타야 갈 수 있는) 👉 5 최종적으로 BFS 순회는 0 1 3 2 4 5 순으로 방문하게 된다. 그 때, 그 때 방문하는 정점마다 가장 가까운 거리의 정점들을 큐에 넣는다.(선입선출) 즉, 들어간지 오래된 정점부터 빠져나오게 된다. 따라서 DFS는 다양한 용도에 사용되며, BFS는 거의 최단 거리 칠 갖기 용도로 사용 된다! [BFS 구현] 큐에 다음에 방..

Part 2-4-3. 그래프 : DFS(깊이 우선 탐색)

DFS(깊이 우선 탐색) [1. 배열로 구현된 그래프 DFS] class Graph { int[,] adj = new int[6, 6] { { 0, 1, 0, 1, 0, 0 }, { 1, 0, 1, 1, 0, 0 }, { 0, 1, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1 }, { 0, 0, 0, 0, 1, 0 }, }; bool[] visited = new bool[6]; // 방문 체크를 위해 public void DFS(int now) // 순회 시작 위치가 인수로 들어 옴 { // 1) now 부터 방문 하고 Console.WriteLine(now); visited[now] = true; // 2) now 와 연결된 정점들을 하나씩 확인해서..

Part 2-4-2. 그래프 : 그래프 이론, 생성

그래프 이론 [그래프의 개념] 현실 세계의 사물이나 추상적인 개념간의 연결 관계를 표현. 정점(Vertex) 👉 데이터를 표현 (사물, 개념 등) 간선(Edge) 👉 정점들을 연결하여 정점 간의 연결 관계를 표현 (간선에 가중치와 같은 값 또한 줄 수도 있다.) 그래프 ex) 소셜 네트워크 관계도 (페이스북 친구 관계) [방향 그래프] 방향이 존재하는 간선을 가진 그래프 방향 그래프 ex) 사람 간의 호감도, 일방 통행이 포함된 도로망 [그래프 순회 방법] 배열이나 리스트는 선형 자료 구조이므로 원소들을 차례대로 순회하면 되지만 그래프는 선형 자료 구조가 아닌, 한 정점에 연결된 정점들이 여러개일 수 있으므로 연결된 정점들 중 다음엔 어떤 정점을 탐색할지 다르므로 순회 방법이 다양하다. 대표적으로 두 가..

Part 2-4-1. 그래프 : 스택과 큐

그래프 [스택과 큐] 둘 다 선형 자료구조이다. 선형 구조 자료란? 자료들이 일렬로 나열된 상태를 말한다. using System; using System.Collections.Generic; namespace Excercise { class Program { static void Main(string[] args) { Stack stack = new Stack(); stack.Push(101); stack.Push(102); stack.Push(103); stack.Push(104); stack.Push(105); int data1 = stack.Pop(); // 105 리턴 및 삭제 int data2 = stack.Peek(); // 104 리턴만 Queue queue = new Queue(); qu..

Part 2-3-4. 미로 준비 : 오른손 법칙

목적지 설정 [Board.cs] using System; using System.Collections.Generic; using System.Text; namespace Algorithm { class Board { const char CIRCLE = '\u25cf'; public TileType[,] Tile { get; private set; } // 맵의 타일들을 담을 배열 public int Size { get; private set; } public int DestY { get; private set; } public int DestX { get; private set; } Player _player; public enum TileType { Empty, // 갈 수 있는 타일 Wall, // ..

반응형