목록전체 글 (47)
게임 개발 로그
Unity 코루틴은 싱글 스레드인데 왜 데이터가 사라졌을까?Unity 코루틴은 기본적으로 메인 스레드에서 실행된다. 그래서 일반적인 멀티스레드 코드에서 말하는 경쟁 조건과는 거리가 있어 보인다.하지만 yield로 실행이 멈춘 사이 다른 요청이 같은 전역 상태를 바꾸면 이야기가 달라진다. 두 코드가 동시에 실행되지 않았더라도, 오래된 작업이 나중에 재개되면서 새로운 요청의 데이터를 읽거나 지울 수 있다.이번 글은 재접속 후 서버에서 주문 데이터를 다시 구성하는 과정에서 발생할 수 있었던 타이밍 문제를 다룬다. 핵심은 Clear() 한 줄이 아니라, 비동기 작업이 자신의 입력 데이터를 언제 소유하게 되는가였다.싱글 스레드는 동시 실행을 막아 줄 뿐, 실행 순서에 따른 상태 충돌까지 막아 주지는 않는다. ..
Unity macOS 네이티브 플러그인을 공용 Bundle로 정리하며 Unity에서 macOS 전용 기능을 추가할 때는 Objective-C 또는 Objective-C++ 소스를 프로젝트 안에 직접 넣는 방법이 있다.Assets/└─ Plugins/ └─ macOS/ └─ NativeFeature.mm 작은 기능을 빠르게 확인할 때는 이 방식이 간단하다. Unity의 macOS Player 빌드 과정에서 .m 또는 .mm 파일이 함께 컴파일되기 때문이다.그런데 기능이 늘어나고 같은 네이티브 코드를 여러 Unity 프로젝트에서 사용하게 되면 관리 방식이 달라져야 했다.이번 작업에서는 Unity 프로젝트 안에 흩어져 있던 macOS 네이티브 소스를 별도의 Xcode Bundle로 옮기고, 하나의..
Unity에서 연속 주문 알림을 디바운스로 묶어 표시하기운영 중인 Unity 애플리케이션에서 주문 종료 이벤트가 짧은 시간 안에 여러 건 연속으로 들어오면, 비슷한 알림이 화면에 반복해서 표시되는 문제가 있었다.기존 구조에서는 이벤트 한 건이 알림 한 건으로 바로 연결됐다. 같은 종목과 같은 주문 유형의 결과도 각각 별도의 알림으로 출력됐고, 사용자는 비슷한 알림의 차이를 구분하기 어려웠다.개별 금액만 표시되다 보니 같은 시점에 처리된 전체 결과를 한눈에 확인하기도 어려웠다. 알림 애니메이션과 표시 대기열 역시 이벤트 수만큼 불필요하게 늘어났다.이번 작업에서는 주문 종료 이벤트를 바로 표시하지 않고 잠시 수집한 뒤, 사용자에게 의미 있는 단위로 그룹화해 하나의 알림으로 보여 주도록 처리 흐름을 수정했다...
기존 실시간 차트에서 이미 지나간 선이 다시 바뀌던 문제 수정하기 기존에 구현돼 있던 실시간 미니차트를 수정하면서, 현재가가 지나간 뒤 이미 그려진 선의 꺾임이 다시 달라지는 문제를 마주했다.차트의 마지막에 표시되는 현재가 head는 실시간 시세에 맞춰 정상적으로 움직이고 있었다. 처음 점이 찍히는 모습도 자연스러웠다.문제는 시간이 조금 지난 뒤였다. 앞에서 이미 지나간 점과 선이 뒤늦게 다른 위치에 그려지면서, 사용자가 봤던 과거 경로가 바뀌는 것처럼 보였다.처음부터 차트 구조를 설계한 상황이 아니었기 때문에, 우선 기존 코드가 어떤 데이터를 기준으로 선을 구성하는지부터 추적해야 했다. 증상부터 다시 확인했다 문제 화면에서는 현재가가 바뀔 때마다 head가 이동하고, 해당 시점의 가격을 따라 선이 이..
Unity에서 실시간 데이터를 표시하는 UI를 만들다 보면 가장 단순한 방법부터 떠올리게 된다. `Update()`에서 값을 읽고, 매 프레임 화면을 다시 그리는 방식이다.private void Update(){ SetCurrentPrice(); SetProfitLoss();}구현은 간단하지만 값이 바뀌지 않은 프레임에도 같은 계산과 UI 갱신이 반복된다. 특히 포트폴리오 목록처럼 여러 아이템이 동시에 표시되는 화면에서는 아이템 수만큼 같은 호출이 늘어나는 구조가 된다.이번 작업도 처음부터 구독 해제 문제를 고치려던 것은 아니었다. 매 프레임 실행되던 현재가와 손익 UI 갱신을 데이터 변경 시점에 맞춰 실행하도록 바꾸는 것이 출발점이었다.문제 상황기존 구조에서는 목록에 표시된 각 아이템이 `U..
1. 행동 트리 설계 2. 행동 정리2-1. 죽음/그로기 상태가장 높은 우선순위를 갖는 상태다. 체력 조건을 검사하여 0보다 작거나 같다면 죽음 상태와 그로기 상태 중 한 가지를 고른다. 만약 첫 번째 죽음이라면 그로기 상태고, 그 이상의 죽음을 맞이했다면 Death 상태로 간다.그로기 상태에서는 이동을 하거나 가만히 있을 수 있다. Groggy(이동) 상태/Groggy 상태 둘 중 한 가지 상태를 선택하게 된다. 2-2. 문 상호작용 상태문과 충돌되어 있으며, F 키를 누르고 있을 때 진행되는 상태다. 맵 중 샛길(지름길)을 열기 위해 문과 상호작용하는 상태다. 2-3. 빠르게 뛰기 상태Q를 눌렀을 때 빠르게 뛸 수 있다. 이동키와 함께 조작해야 한다. 빠르게 뛸 때 스태미나가 필요하다. 빠르게 달리..
참고 영상 참고 영상과 실제 개발된 화면에 차이가 있는 이유는 빌트인 프로젝트와 URP 프로젝트에 차이가 있기 때문이다. URP 프로젝트에서는 따로 Surface Shdaer가 없기 때문에 해당 영상에서 제시하는 셰이더대로 제작하는 것에 무리가 있다.그래서 Shader Graph를 만들어서 해당 기능을 적용하는 방법을 따로 노션에 정리해 두었다. 참고 영상과 결과물에 차이가 있기 때문에 좀 더 업데이트가 필요하지만 현재까지의 해결법을 적은 노션 링크를 올려 두겠다. Field of View | Notion1. 해결법 참고 영상metal-catamaran-8b6.notion.site
1. 설거지 시스템WashingArea설거지 시스템이 구현되는 공간에 대한 클래스다. WasingArea는 WashingUI, Plate를 참조하여 가지고 있다. 역할Plate 풀링: WashingArea는 Plate를 담은 Queue와 List가 있다. 사용 가능한 접시를 Queue에 넣어두고 있으며, 사용할 때는 Queue에서 꺼내서 List에 담는다.Plate 생성: WashingArea에는 CreatePoint(Vector3)가 있다. 이 CreatePoint에서 Plate를 생성하는 역할을 한다. Plate를 생성할 때는 난이도(level)에 따라 Plate의 hp와 한번에 생성되는 Plate의 개수를 랜덤성을 적용하여 생성한다.Plate 삭제: 현재 선택된 Plate(selectPlate)의..
문제N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오. 입력첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다. 출력첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다. 성공 코드 머지 소트를 연습하기 위해서 머지 소트를 구현해 봤다. 첫 제출에 시간 초과로 실패가 떴는데, 그 이유는 입출력 속도 탓이었다. 버릇처럼 endl을 사용하는 바람에 시간 초과가 떴고, endl 대신 "\n"을 넣어서 성공할 수 있었다.#include #include using namespace std;vector nums..