안녕하세요 강의 참고하면서 서버 만들어 보고 있는데 https://learn.microsoft.com/ko-kr/dotnet/api/system.net.sockets.socketasynceventargs?view=net-8.0#remarks 해당 문서에서 pooling이 있더라구요 생각해보니 동접이 꽤 많다라고 가정하면(약 3000?) 이 SocketAsyncEventArgs 생성 소멸이 많이 일어난다고 생각했습니다. 그래서 pooling을 한번 만들어보고 있는데 만드는 중에 Dispose를 언제 해줘야 할지 감이 잘 안옵니다. 현재는 Client가 Disconnect될 때 Push하게 되는데 Push에서 poolCount가 3000이 넘으면 이걸 AllClear라는걸로 pool에 있는 SocketAsyncEventArgs를 다 Dispose해주는 상황인데 이렇게하면 3000이 넘기 전까지는 메모리에 계속 남아 있으니 먼가 찜찜합니다. 이런 문제가 있는데 좋은 해결책이 있을까요? 감사합니다!
안녕하세요. 강의 정말 잘 보고 있습니다. JobQueue의 Push 함수를 호출하는 스레드가 Action까지 처리하게 되는데, 이는 Push를 호출하는 시점부터 해당 Queue에 모든 Job이 비워질 때까지 Caller가 Blocked 됩니다. 이를 JobQueue의 Pop과 Action.Invoke를 담당하는 스레드를 하나 만들고, 백그라운드에서 폴링하는 방식으로 만들려 합니다. 즉, Push를 호출한 스레드를 사용할 지, 미리 스레드를 만들어두고 폴링하는 방식으로 사용할 지의 차이인 것 같습니다. 두 방식 중 어느 방식이 나을지 알고 싶습니다. 감사합니다.
안녕하세요 오늘부터 수강 시작했는데 좋은 강의 감사합니다 Spawner에서 var goObj =Base_Mng .Pool.Pooling_OBJ("Monster") .Get((value) => { value. '''''''' value.''''''''' value.'''''''' }); 여기서 Get 다음에 value 가 헷갈립니다 ...일회성 함수 만들어서 실행하고 끝인지 ..정확하게 모르겠네요 액션 인데 저게 어떤 의미인지 대충은 알겠는데.. 이해가 안됩니다 ㅠ 다른부분은 자세하게 설명해주셨는데 이부분만 부탁드립니다
안녕하세요 개인 프로젝트에 적용하는 과정에서 문제가 발생해서 질문드립니다. 제 스프라이트 중 하나가 SpriteMode가 Multiple로 설정되어 있어서, 해당 스프라이트를 리소스매니저 Get호출할 때 아래와 같은 오류가 발생하고 있습니다. System.Exception: Unable to load asset of type UnityEngine.Sprite from location Assets/03.Resources/Sprites/UI/Game_Main/ico_misc 1.png[ico_misc 1]. UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate () (at ./Library/PackageCache/com.unity.addressables@1.21.21/Runtime/ResourceManager/Util/DelayedActionManager.cs:162) 이 오류를 어떻게 해결할 수 있을까요??
1 .클라이언트-서버 방식 클라이언트가 입력을 보내면 중앙서버 에서 로직(충돌,이동) 이런걸 처리하고 게임상태를 업데이트하고 클라이언트한테 보내주는 방식이있고 p2p 방식 p2p 방식으로 모든 클라이언트가 동등한 지위에서 서로 통신하는 구조로 알고있는대 여기서 질문이있습니다 유니티랑 연동한다고 가정하였을때 클라이언트 -서버 방식을 이용하게 되면 유니티에 내장 기능 (컴포넌트)등을 이용해 동기화는 못하게 될꺼같은대 서버단에서 충돌 처리하는 로직을 만들어서 사용해야만 하는지? p2p 방식은 그나마 유니티 내장 기능을 자유롭게 사용할수 있을꺼 같고 p2p 방식을 이용한다면 서버를 따로 구동하는 게 아닌 클라이언트단에서 서버를 구동하는것인가요?
수강생들이 혹시나 동일한 경험할까봐 남겨둡니다. 재현방법 실행 Lobby에서 InventoryUI 오픈 InventoryUI에서 EquipmentUI 오픈 ESC 입력하여 EquipmentUI 닫기 ESC 입력 재현결과 InventoryUI 위에 게임을 종료하시겠습니까 ConfirmUI 오픈 기대결과 InventoryUI 닫기 재현버전(강의) 진행 이후 수정되었을 수도 있어서 적어만 둡니다. 아이템 장착 Pt.4 사유 이전에 GoodsUI를 추가 하면서 OpenUI() 중 여는 ui의 siblingIndex를 childCount - 1 로 수정하였습니다. 하지만 CloseUI() 할 때 그 다음 lastChild를 childCount -2 로 조회하는 것으로 수정하지 않았습니다. 이 결과, 해당 재현 상황에서 UIManager의 CloseUI() 중 lastChild로 InventoryUI가 들어와야 하는데 GoodsUI로 들어오게 됩니다. GoodsUI는 BaseUI를 상속하지 않으므로 GetComponent<BaseUI> 후 설정되는 m_FrontUI가 null이 됩니다. 이후 ESC를 누르면 m_FrontUI가 null이므로 InventoryUI가 있음에도 게임 종료 ConfirmUI가 노출됩니다. 간이 해결 CloseUI시 frontUI에 GoodsUI가 아닌 그 다음 UI가 제대로 들어가게 하기. UIManager.cs CloseUI() 수정하기 var lastChild = UICanvasTrs.GetChild(UICanvasTrs.childCount - 2);
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Algorithm { class Board { const char CIRCLE = '\u25cf'; // \u25cf = ● public TileType[,] _tile; // 배열 public int _size; public enum TileType { Empty, Wall, } public void Initialize(int size) { _tile = new TileType[size, size]; _size = size; for(int y = 0; y < _size; y++) { for(int x = 0; x < _size; x++) { if (x == 0 || x == _size - 1 || y == 0 || y == _size - 1) _tile[y, x] = TileType.Wall; else _tile[y, x] |= TileType.Empty; } } } public void Render() { ConsoleColor prevColor = Console.ForegroundColor; for (int y = 0; y < _size; y++) { for (int x = 0; x < _size; x++) { Console.ForegroundColor = GetTileColor(_tile[y, x]); Console.Write(CIRCLE); } Console.WriteLine(); } Console.ForegroundColor= prevColor; } ConsoleColor GetTileColor(TileType type) { switch(type) { case TileType.Empty: return ConsoleColor.Green; case TileType.Wall: return ConsoleColor.Red; default: return ConsoleColor.Green; } } } } using System; namespace Algorithm { class Program { static void Main(string[] args) { Board board = new Board(); board.Initialize(25); Console.CursorVisible = false; // 커서가 안 보임 const int WAIT_TICK = 1000 / 30; int lastTick = 0; // 마지막 시간 while (true) { #region 프레임 관리 // 시스템이 시작되고 난 후 시간으로 넣음 int currentTick = System.Environment.TickCount; // 1000/30이라고 쓴 이유는 ms(밀리세컨드)떄문에 // 1/30라고 안 쓰고 1000을 곱해줘서 작성한다. if (currentTick - lastTick > WAIT_TICK) continue; lastTick = currentTick; #endregion // 렌더링 Console.SetCursorPosition(0, 0); // 커서 위치를 (0, 0)으로 설정 board.Render(); } } } }
학습 관련 질문을 남겨주세요. 먼저 유사한 질문이 있는지 검색 부탁 드립니다. 질문 내용이 상세할수록 명확한 답변을 드릴 수 있습니다. 진행에 문제가 있는건 아니구요. 강사님께서 스트링을 말아서 로그 쏘실 때 두가지 방식으로 나뉘더라구요. Logger.Log($"SerialNumber: {item.SerialNumber} ItemId: {item.ItemId}"); Logger.Log("Load failed (" + e.Message + ")"); 강사님은 역할이 구분되어 있던데 어떤 차이를 두고 사용하시는지 단순 궁금합니다. 메시지는 무조건 string이니까 그런건지.. 가독성 측면에서 이점이 있는건지.. 유지보수에서 도움이 되는건지..
안녕하세요 선생님 유니티 왕초보 질문 드립니다. 강의 수강 도중 Pt.1 마지막 부분 Equipment UI 창 부분에서 아이템 클릭 시 모든 아이템의 백그라운드 이미지가 Legendary(빨강색)로 설정되어 있는 것으로 보이는데요, Pt.2 파트로 넘어오니 작업한 게 없는거 같은데 각 아이템의 백그라운드 이미지가 등급에 맞게 조절되어 있는거 같습니다. 현재 Pt.4 파트 수강 중인데 아이템 장착 / 탈착 시 각 파츠에 EquippedItemIcon이 제대로 표기되지 않는거 같아 문의드립니다.
Coroutine을 적극 권장하신다고 하셨는데 new연산자로 코루틴은 인스턴스를 만들고 그로인해 가비지가 생성된다고 알고 있습니다. 이런 이유로 대안으로 uniTask가 나왔다고 들었습니다. 아직 uniTask보다 Coroutine이 보편화되어있고 성능적 이점이 크게 차이가 나지 않는 지 궁굼합니다.