반응형

공부 624

Part 4-2-5. 멀티쓰레드 프로그래밍 : 메모리 배리어

멀티 쓰레드 이전 시간에서는 컴파일러가 소스 코드를 최적화하여 우리가 원하던 방향으로 정상적으로 작동하지 않는 문제가 발생하였다. 그러나 사실 컴파일러 뿐만 아니라 소스 코드를 최적화 하는 또 다른 존재가 있었으니 바로 하드웨어(HW)이다. 따라서 오늘 실습할 것은 하드웨어가 진행하는 최적화 메모리 배리어에 대해서 학습해보겠다. 🤠 코드는 아래와 같다. class Program { static int x = 0; static int y = 0; static int r1 = 0; static int r2 = 0; static void Thread_1() { y = 1; // Store y r1 = x; // Load x } static void Thread_2() { x = 1; // Store x r2 ..

신입 버릇 팀장까지 간다! 일잘러의 7가지 습관

[쌩신입 완벽 적응 가이드] 일잘러 될 신입사원은 떡잎부터 다르다 ‘세 살 버릇 여든까지 간다’ 한국인이라면 귀에 못이 박히도록 들은 속담이 아닐까요? 한번 들인 버릇은 여간해서 고치기 힘들다는 뜻을 담고 있지요. 한번 굳어진 행동 방식은 나를 어떤 식으로든 변화시켜요. 좋은 습관 하나가 내 인생에 큰 영향을 미치기도 하고, 나쁜 습관 하나가 한 사람의 건강을 해치기도 합니다. 그렇기 때문에 처음부터 좋은 습관을 만드는 것은 백 번 강조해도 지나치지 않아요. 직장생활도 삶과 마찬가지예요. 신입사원 시기는 모든 상황이 낯설고, 그래서 뭐든 새로 익혀야 하죠. 이때 처음 익힌 습관이 장기적인 커리어에 영향을 줄 수 있죠. 업무 습관도 생활 습관과 다르지 않아서, 연차가 쌓여 비슷한 일을 대할 때 그 습관이 ..

공부/자기계발 2023.09.06

Part 4-2-4. 멀티쓰레드 프로그래밍 : 캐시 이론

멀티 쓰레드 캐시 지난번과 동일하게 패밀리 레스토랑을 예로 들어 이해해보자 👍 지난시간 우리는 패밀리 레스토랑인 아웃백을 개업하고 직원(로봇)을 채용해 영혼을 통해 로봇을 움직였다. 그러나 레스토랑이 궤도에 올라서 손님도 많아지고 돈도 많아졌는데 손님이 몰리다보니 일처리를 어떻게 해야할지 고민이 생긴것이다. 오른쪽을 보면 주문 현황을 볼 수 있다. 테이블을 돌아다니며 주문을 받는 직원이 있는데 주문을 받으면 주방으로 전달을 해야 주문이 들어간다. 이 식당에는 주문 현황 기계가 있는데 이 기계에 주문을 기입하면 주방에서 주문서가 나와 음식 조리가 시작된다. 그런데 하나의 문제가 있다. 주문 현황판이 멀리 있다는 것이다. 그렇다면 직원은 이를 어떻게 해결하는 것이 가장 좋을까? 다양한 해결 방법이 있다. 1..

Part 4-2-3. 멀티쓰레드 프로그래밍 : 컴파일러 최적화

멀티 쓰레드 컴파일러 최적화 using System; using System.Threading; namespace ServerCore { class Program { static bool _stop = false; static void ThreadMain() { Console.WriteLine("쓰레드 시작!"); while (_stop == false) { // 누군가 stop 신호를 해주기를 기다린다! } Console.WriteLine("쓰레드 종료!"); } static void Main(string[] args) { // 메인에서 쓰레드를 생성하고 실행한다 Task t = new Task(ThreadMain); t.Start(); // 멈춘다 _stop = true; Console.WriteLi..

Part 4-2-2. 멀티쓰레드 프로그래밍 : 쓰레드 생성

멀티 쓰레드 정직원 쓰레드 생성 using System.Threading; class Program { static void MainThread(object state) { Console.WriteLine("Hello, Thread!"); } // 메인 직원 static void Main(string[] args) { // 직원을 한명 더 고용하고, 일을 시킨다. Thread t = new Thread(MainThread); t.Start(); Console.WriteLine("Hello, World!"); } } 쓰레드를 생성하고 초기화 하는 것은 어렵지 않다. Thread t = new Thread()로 새로운 쓰레드를 만들어준다. 새로운 메서드를 MainThread라고 만들어주고 생성한 쓰레드 안에..

Part 4-2-1. 멀티쓰레드 프로그래밍 : 멀티쓰레드 개론

멀티 쓰레드 서버는 멀티쓰레드를 활용한다. 여태까지 자료구조와 알고리즘은 기초 지식이 없어도 충분히 이해하고 활용할 수 있지만, 멀티쓰레드부터는 원할한 이해를 위해선 컴퓨터 구조 원리와 운영체제의 기본 지식이 필요하다. 따라서 오늘은 당장 코드로 이런, 저런 작업을 하는 것이 아닌 멀티쓰레드 개론에 대해서 얘기한다. 서버를 운영하는 것은 식당을 운영하는 것과 같다. 우리가 크게 한식, 일식, 그리고 이보다 규모가 조금 큰 패밀리 레스토랑 총 3가지의 식당을 운영한다고 가정해보자. 로봇 직원은 혼자서 아무것도 하지 못하는 상황이며, 식당 관리자인 우리는 영혼을 각 식당의 로봇에게 부여한다고 한다. 이 때 영혼도 1개라고 가정한다. 그렇다면 영혼이 1개인데 각 식당의 로봇을 어떻게 관리하고 일을 시킬수 있을..

Part 4-1-1. 서버 OT 및 환경 설정

게임 서버 개론 서버란? 서버 👉 다른 컴퓨터에서 연결이 가능하도록 대기 상태로 상시 실행 중인 프로그램 영업 중인 식당과 유사하다. 손님이 올 수 있도록 식당 열고 대기하다가 손님 오면 서비스 제공 ✈ 서버의 종류 1️⃣ Web Server 1️⃣ Web Server ex) HTTP 질의/응답 형태 1. 정보 요청/갱신이 드물다. 2. 한번만 질의 응담 받고 떠남 단순히 한번만 교류 간단한 요청과 그에 대한 응답을 할 때 많이 사용한다. 예를 들어 로그인, 랭킹 시스템 불러오기 같은 단발성으로 불러오고 말 것들은 웹서버를 사용하는 것이 좋을 것 같다. 3. 실시간 상호 교류가 필요하지 않다. 4. 식당에서 직원이 손님에게 먼저 접근하는 일이 없다. 즉, 서버가 먼저 클라에게 접근하는 일이 없다. 테이크..

Part 3-13-9. 미니 RPG : 몬스터 자동 생성, 完

미니 RPG 몬스터 자동 리스폰 서버 측에서 한다. 몬스터가 죽으면 몬스터의 전체적인 숫자를 맞춰주기 위해 랜덤한 위치에서 스폰을 한다. 이렇게 서버측에서 스폰을 한 후 클라이언트에게 알려준다. 📜 GameManager public Action OnSpawnEvent; public GameObject Spawn(Define.WorldObject type, string path, Transform parent = null) { GameObject go = Managers.Resource.Instantiate(path, parent); switch(type) { case Define.WorldObject.Monster: _monsters.Add(go); if (OnSpawnEvent != null) OnSp..

Part 3-13-8. 미니 RPG : 레벨업

미니 RPG 레벨업 ✈ 스탯 데이터 📄StatData.json { "stats": [ { "level": "1", "maxHp": "200", "attack": "20", "totalExp": "0" }, { "level": "2", "maxHp": "250", "attack": "25", "totalExp": "10" }, { "level": "3", "maxHp": "300", "attack": "30", "totalExp": "20" } ] } 각 레벨에서의 기본 스탯 📜Stat [Serializable] public class Stat { public int level; public int maxHp; public int attack; public int totalExp; } json파일의 내용과..

Part 3-13-7. 미니 RPG : Destory

미니 RPG Destroy 오브젝트가 Destroy 될 때 오브젝트가 메모리 해제되면 유니티의 Object의 == 연산자 오버로딩으로 인하여 해제된 객체를 == null 비교 연산할 땐 그 객체를 참조하는 참조 변수들은 댕글링 포인터가 되는 것이 아닌 “null”이 되도록 처리된다. 따라서 해제된 오브젝트의 컴포넌트를 참조하는 것들을 잘 확인해야 한다. 크러쉬가 날테니까! 오브젝트가 해제되면 당연히 그 오브젝트의 컴포넌트들에도 참조할 수 없다. 형변환 연산 비용 줄이는 대안 📜GameManager 에서 오브젝트들을 스폰하고 디스폰하는 작업을 할 것이다. 근데 어떤 오브젝트를 스폰해야하는지를 알아야 한다. 그러면 📜BaseController 타입으로 업캐스팅해서 받는 방법도 있을테고(근데 이러면 상속이 아..

Part 3-13-6. 미니 RPG : 몬스터 AI

미니 RPG 몬스터 AI 📜BaseController 👉 플레이어와 몬스터의 공통적인 속성과 기능 모음 1. 📜PlayerController 2. 📜MonsterController 📜MonsterController와 📜PlayerController의 공통적인 함수 및 멤버들은 📜BaseController로 옮겨주었다. 몬스터 애니메이션 컨트롤러의 애니메이션 클립의 이름들도 플레이어 애니메이션 컨트롤러와 동일하게. 📜MonsterController 몬스터 오브젝트에 붙여준다. 📜PlayerController 와 상당수 비슷하다. 여기에 없는건 📜BaseController로부터 상속 받는다. using System.Collections; using System.Collections.Generic; using..

Part 3-13-5. 미니 RPG : 체력 게이지

미니 RPG 체력 게이지 UI 만들기 체력 게이지는 몬스터와 플레이어 위에 따라다녀야함. 그러니 원근법 적용이 되야 한다. 3D 오브젝트처럼! 따라서 캔버스 렌더러 모드를 World Space로 바꿔준다. UI_HPBar : 캔버스 👉 RenderMode는 WorldSpace. 이땐 이 캔버스를 찍을 카메라도 할당해주어야 하는데, RenderMode, Camera 둘 다 코드로 로드해줄 것이다. HPBar : 슬라이더 이제 캔버스는 게임 월드 기준 좌표를 가지므로 캔버스와 슬라이더의 위치와 크기를 잘 맞춰주고 최종적으로 UI_HPBar 캔버스를 프리팹으로 만들어준다. 게임이 시작되면 몬스터와 플레이어의 산하 자식으로 Instantiate 시켜주어 몬스터와 플레이어를 따라다니게 할 것이다. 공격시 체력 깎..

Part 3-13-3. 미니 RPG : 타겟 락온

미니 RPG 📜Define public enum MouseEvent { Press, PointerDown, // 마우스 뗀 상태에서 처음 눌렀을 때 PointerUp, // 마우스 누르고 있던 상태에서 처음 뗏을 때 Click, } Press : 누르는 동안 PointerDown : 안 누르고 있던 상태에서 처음으로 눌렀을 때 PointerUp : 0.2초 이상 꾹 누르고 있던 상태에서 처음으로 뗏을 때 (꽤 누르고 있다가 뗐을 때) Click : 0.2초 이하로 누르고 있던 상태에서 처음으로 뗏을 때 (말 그대로 클릭 수준. 찰나만 누르고 뗐을 떄) 📜InputManager public class InputManager { public Action KeyAction = null; public Actio..

Part 3-13-2. 미니 RPG : 스탯 설정, 마우스 커서 변경

미니 RPG 스탯 📜Stat 👉 스탯을 가지는 모든 것들이 공통적으로 가지는 속성들 📜PlayerStat 👉 Stat을 상속 받음. 플레이어의 스탯 (플레이어 오브젝트에 붙는다.) 📜MonsterStat 👉 Stat을 상속 받음. 몬스터의 스탯 (몬스터 오브젝트에 붙는다) 📜Stat using System.Collections; using System.Collections.Generic; using UnityEngine; public class Stat : MonoBehaviour { // 멤버 변수 [SerializeField] protected int _level; [SerializeField] protected int _hp; [SerializeField] protected int _maxHp; [..

Part 3-13-1. 미니 RPG : 환경 설정, 이동

미니 RPG 게임을 만들 때 빈 프로젝트에서 처음부터 쌓아나가는 식으로 만들지 말고 여태까지 해온 온갖 매니저들 등등 이런 나만의 프레임 워크를 미리 구축해놓고 이를 활용해 만들어 나가기를 추천한다고 하셨다. 풀링 매니저, UI 매니저 등등 이런건 어떤 게임을 만들든 다 필요하다. Light 연산 RealTime 실시간으로 빛을 연산하겠다는 의미 이로 인해 성능 부하가 어마어마 하다. 그리고 움직이는 오브젝트라면 그 오브젝트의 빛 연산을 미리 Baked 할 수 없다. 어떻게 움직일 줄 알고 하겠는가? 🤯 Baked 이미 계산 완료 후 에셋으로 저장해놓은 라이트맵을 이용해서 게임 실행 중에 라이트 연산을 하지 않고 이를 덮어 쓴다. 라이트맵은 빛을 받으면 어떤 색으로 보일지 그림자는 어떻게 할지 등등 미리..

Part 3-12-1. Data : Json을 이용한 Data Manager

Data Data Manager 게임 내의 모든 수치, 데이터들을 관리하는 Manager 하드 코딩으로 수치를 세팅하고 바꾸는 것은 관리차원에서도 문제가 되고 더 큰 문제는 하드코딩된 수치는 exe 실행파일에 묶여 들어가기 때문이다. 나중에 수치를 변경해야할 업데이트 사항이 생긴다면 수정해서 만든 새로운 exe를 배포를 아예 다시 해야하는 일이 발생하는 것이다. 👉 따라서 모든 수치와 연관된 모든 데이터들을 모아둔 것을 따로 별도의 파일로 만든다. 일반적으로 json이나 XML파일로 만든다. 게임을 실행했을 때 웹 통신을 이용하여 데이터 파일 내용을 살짝 수정하기만 하면 되기 때문에 게임을 실행할 때 그 바뀐 데이터 파일을 로드해서 실행하게 되므로 게임 실행 파일을 수정하고 새배포 해야하는 그런 일은 하..

Part 3-11-1. Corutine : 코루틴 최적화, 커스텀

Corutine 코루틴은 하나의 프로세스를 여러 루틴들이 시간을 나눠서 사용하는 방식으로 스레드와는 다르다. 스레드는 동시에 여러 프로세스가 여러 작업을 병렬적으로 진행하는 것. 즉 코루틴은 직렬처리이며 병렬처리처럼 보이게끔 해주는 함수이다. 유니티는 병렬적으로 함수들을 동시에 여러가지 실행하지 못한다. 한번에 함수를 하나하나 실행시켜주는 것이다. 코루틴 원리 class Test { public int id = 0; } class CoroutineTest : IEnumerable { public IEnumerator GetEnumerator() // 인터페이스 구현 { yield return new Test() { id = 1 }; // Test 객체 리턴 후 다시 돌아 와서 밑에 실행 yield ret..

반응형