[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
(위에 사진은 3d 방향 및 이동 동기화를 성공해서, 뿌듯해서 같이 올려요 ㅎ..ㅎ) 멀티환경에서 3D이동 및 회전을 동기화를 구현할 때, 이전 위치와 현재 위치의 Vector3.magnitude의 차이가 0.1이 나면 이동패킷을 보내줄수있도록 설계를 해서 구현을 했습니다. 혹시 0.1f 차이마다 패킷을 계속 보내는 것도 패킷을 너무 많이 보내는 편인가요? (유저 수는 10명정도가 같은 room에 있도록 만들예정입니다) 항상 감사합니다! 강의를 들으면서 조금씩 바꿔보는데 정말 뿌듯하네요 하하하하하 강의가 너무 유익해요^^
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. public override bool Equals(object other) => base.Equals(other); 이 부분이 왜 추가가 되는건지 궁금합니다. 어짜피 Category 파라미터가 아닌 object형 파라미터는 재정의 안하면 자동으로 base의 Equals를 호출하는게 아닌가요? 이 부분이 헷갈려서... 질문드립니다
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
저희 강의에서 멀티쓰레드를 사용하는 걸로 알고 있는데 쓰레드를 생성하는 부분이 정확히 어디 부분인가요..? 해당 부분에서 Connect 될 때 필요하다면 count의 개수만큼 쓰레드를 생성하는 걸까요..? 혹시 아니라면 어디 부분일까요... 도저히 못 찾겠어서 질문드립니다..!
2021.3.20f1 버전 사용중입니다. 기존 Text가 UI의 Legacy 폴더 안에 있고 원래 Text가 있던 자리에 TextMeshPro가 있네요. 인터넷을 좀 찾아봐도 TextMeshPro를 권장하는 사람들이 많더라구요 시간이 지나면서 새로운 버전이 나온것 같던데 사용법이 비슷하면 TextMeshPro를 사용하는게 더 좋겠죠?
public void Connect(IPEndPoint endPoint, Session session) // 사용하는 부분 //connector.Connect(serverEndPoint, () => { return new GameSession(); }); GameSession gameSession = new GameSession(); connector.Connect(serverEndPoint, gameSession); Func 형 말고 그냥 Session을 참조로 받아서 하면 안되나요? 코드가 돌긴 하던데..
대학 게임학과에 재학 중인 학생입니다. 교수님과 게임서버프로그래밍에 대해 상담을 나누는 도중 교수님께서 MMORPG를 포함한 대부분의 프로젝트에서 서버를 직접 만드는 경우는 거의 없고 언리얼 데디케이트, 포톤, 프라우드넷 같은 이미 만들어진 모델이나 서버엔진을 사용한다고 말씀하셨는데 정말인가요? 보통 반대로 대부분의 프로젝트가 게임에 맞춰 서버엔진을 제작하는 줄 알았는데 제가 알던 상식과는 너무 달라서 질문드립니다.
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
실무에 가깝게 적용할만한 캐릭터간 이동 동기화 중에서 딜레이후 동기화 처리에 대한 참고할만한 이론이나 문서 같은것이 있을까요? 게임 장르는 존 방식이고 한 방에 최대 100명 이하? 정도 될것 같은데요 환경은 모바일이고요 약.. 서버에서 1초에 4~8번 정도(정확히 아직 1초에 몇번 보내는지는 모릅니다)의 이동관련 패킷을 TCP나 UDP로 보낸다고 가정할 경우 일정 시간 이동 관련 위치 값을 수집해서 보간 처리 해볼까 하는데 언리얼 데디케이트 서버에서 어떻게 해야 할지 좀 막막한것 같은데 관련된 문서나 방식등이 있을까요? 루키스님 강의 중 C++ 쪽 서버강의에서 이미 강의는 어느정도 듣긴했지만 이동 관련된것이 없는것 같아서 질문 남깁니다 답변좀 부탁드리겠습니다!
안녕하세요, 수업은 다 듣고 실습부분만 조금씩 다시 따라가고 있는데요, 카트레이싱에서 환경 구축을 다 하고, KartAgent 코드도 깃허브에 있는거 그대로 C# 코드 옮기고, AcadeKart 코드도 수정을 다 했는데, 이상하게 카트가 1번 웨이포인트 지나고 리셋이 됩니다. 파이토치와 유니티 책에는 OnEpisode 함수에 for문이 있는데, 넣고 빼고는 상관이 없더라구요, 웨이포인트를 이어가지 못하거나 중간에 충돌이라고 판단하거나 기타 리셋 조건이 문제인것 같은데, 어딜 봐야 할지 조언을 주실 수 있으신가요?
void Start() { Bind<Button>(typeof(Buttons)); Bind<TextMeshProUGUI>(typeof(Texts)); Get<TextMeshProUGUI>((int)Texts.ScoreText).text = "Bind Test"; } void Bind<T>(Type type) where T : UnityEngine.Object //reflection 사용 { string[]names = Enum.GetNames(type); UnityEngine.Object[] objects = new UnityEngine.Object[names.Length]; _objects.Add(typeof(T), objects); for (int i = 0; i<names.Length;i++) { objects[i] = Util.FindChild<T>(gameObject, names[i], true); } } T Get<T>(int idx) where T : UnityEngine.Object { UnityEngine.Object[] objects = null; if (_objects.TryGetValue(typeof(T), out objects)==false) return null; return objects[idx] as T; } 기존에 Text를 TextMeshProUGUI로 바꾸고 using TMPro;도 추가했는데도 계속해서 해당 오류가 발생하네요...도저히 원인을 못찾겠습니다 ㅠㅠ
우선 저는 단순히 Lock 만 사용하면 무수한 경합으로 인해 성능적으로 손해를 볼 수 있어 Job Queue 를 사용하는 것으로 이해를 했습니다. 그래서 이것저것 연습하면서 Job Queue 를 계속 사용하고 있는데 도중에 몇몇 의문이 생기어 질문을 드리게 되었습니다. Job Queue 를 사용하다보면 Job Queue 내에 또 다른 Job Queue 를 사용해야하는 상황이 발생하는데 이 부분은 문제가 되지 않을까요? 아래는 예시 코드입니다. public void Function() { MatchingManager.Instance.Push(() => { ... User.Party.Push(() => { ... }); }); } Lock 처럼 사용하면 된다 라는 생각은 옳은 것인가요? 아니면 Lock 과는 달리 Job Queue 사용 시 주의 할 부분이 있을까요? 항상 양질의 강의를 제공해주셔서 감사드립니다.
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
안녕하세요 강사님! 다름이 아니라 강의를 따라해보고 그 뒤에 거의 흡사하게 한 번더 다른 파일에서 코드를 구현해보고 있습니다. 그런데 서버에서 클라에 패킷보내는것까진 제대로 작동하는데(좌표확인까지됨) 클라에서 실제로 테스트를 위해 실행했을때 실질적인 플레이어캐릭터가 좌표 인식을 제대로 못하는 문제가 있습니다. 구체적으로 첫번째클라를 실행하고 플레이어이동시키고잇는도중 두번째클라가 실행되면 두번째클라에서도 첫번째클라플레이어 이동이 제대로 동기화되어보이는데 이후 두번째클라창으로 옮겨가서 플레이어를 이동시키면 첫번째클라창에서 타플레이어좌표이동이 플레이어오브젝트에 반영되지않고 방향과 상태만 반영됩니다. 이후 첫번째클라창으로 옮겨가 플레이어를 이동시키면 두번째클라창에서도 타플레이어좌표이동이 되지 않습니다. 와중에 서버에서 클라쪽에 패킷전송은 잘되고 있습니다. 게다가 타플레이어가 실제로 이동한좌표로 가려고하면 충돌인식까진되는데 화면엔 타플레이어가 이동하기전 있던곳에 그대로 서있습니다 이경우엔 보통 어떤부분이 문제인걸까요?ㅜㅜ +) break point 걸어놓고 유니티에서 확인해봤는데 유니티에서 실행하면 정상적으로 이동동기화 되는데 build를 해서 만든 exe파일에선 위와 같은 현상이 일어나며 적용이 안됩니다...
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
안녕하세요 강사님 30분경에 '실질적으로 지금보다 좀 더 복잡한 MMO가 되면 불러와야 할 정보들을 클라에게 먼저 알려준 다음 클라에서 모든 정보 불러오기가 끝났으면 서버쪽에 준비됐다고 ok패킷을 날리게 되고 ok패킷을 받고나서야 서버쪽에서 게임에 입장 시킨다고 하시면서 여기까지는 구현하지 않을거라고 하셨는데 해당 내용이 나중에 강의중에(다른파트에서라도) 나오는지 궁금합니다! 혹시 강의중에 해당 내용이 없다면 구글링 검색어를 뭘로 하면 좋을지 알려주시면 감사하겠습니다!
파일을 다운받고 게임을 실행하니 Assets\Scripts\Manager\IAPManager.cs(9,27): error CS0535: 'IAPManager' does not implement interface member 'IStoreListener.OnInitializeFailed(InitializationFailureReason, string?)' 위와 같은 에러가 뜨네요. 유니티 버전은 2021.3.21f1입니다.
public static ArraySegment<byte> Open(int reserveSize) { if (CurrentBuffer.Value == null) { CurrentBuffer.Value = new SendBuffer(ChunkSize); } if (CurrentBuffer.Value.FreeSize < reserveSize) { CurrentBuffer.Value = new SendBuffer(ChunkSize); } return CurrentBuffer.Value.Open(reserveSize); } Sendbuffer에서 남은버퍼를 반환해주는 open함수에서 필요한 사이즈가 현재 남아있는 free사이즈보다 큰 경우(CurrentBuffer.Value.FreeSize < reserveSize) 새로 sendbuffer를 CurrentBuffer.Value에 넣는데, 아직 CurrentBuffer.Value 에 보내지 못한 데이터가 있는 경우에 open을 해버리면 새 sendbuffer가 CurrentBuffer.Value로 치환되어버려서 데이터가 날라가버리는 것 아닌가요? 즉, 예를들어 아직 100명한테 다 안보냈는데 새로 할당해버리면 안되지않나요? _usedSize를 recvbuffer에서처럼 땡겨서 쓰지 않는 이유가 누군가가 계속 이전에 있던 부분(현재 사용 중인 부분)을 참조하고 있을 수도 있기 때문에 그냥 증가시키는 방법으로 한 것 처럼.. CurrentBuffer.Value 도 저렇게 그냥 새로 할당해버리면 안될 것 같다고 생각이 계속 듭니다 ㅜㅜ
질문 1. TLS로 SendBuffer를 스레드별 전역변수로 지정했으면, SendBuffer 멤버필드인 buffer도 스레드별 전역변수가 아닌가요? 그런데 왜 _buffer는 공유자원처럼 다수의 스레드가 참조하는 건가요?(28:39 부분) 질문 2. 만약 _buffer는 TLS 여도 다수의 스레드가 볼 수 있다고 쳐도, 어차피 Send하는 부분은 그 스레드가 넣은 부분만(handler에서 close로 보내준 segment영역) 보내주기때문에 상관없는 것 아닌가요? (하지만 애초에 질문 1이 이해가 안됩니다.) 질문 3. 이전에 Session#2 강의 시작부분에 설명해주신 내용에서, SEssion의 receive는 OnRecvCompleted()메서드에 여러 스레드가 동시다발적으로 들어가는 경우는 없다. 라고 하셨는데, 해당 강의에서는 어떤 이유로 멀티스레드를 생각해야 하는 상황이 된건지 궁금합니다. 질문 4. Session 객체는 connect되는 client당 하나씩이니까 client와 연결 될 때 마다 새로운 session객체가 생성되어 다 따로 만들어지는 것이기 때문에 애초에 _sendQueue도 스레드별로 따로 아닌가요? 질문 5. _buffer는에서 읽기만 하는거니까..(30:03) 라고 하셨는데 읽는 부분이 어느부분인지, deq하는것을 읽는것이라고 표현하신건가요? 어떤 경우들을 말슴하시는건지 이해가 안되어 헷갈리는게 많습니다. 일단 질문은 더 있지만, 대표적인 질문들로 올려봅니다
Session#2 강의 시작부분에 설명해주신 내용에서, SEssion의 receive는 OnRecvCompleted()메서드에 여러 스레드가 동시다발적으로 들어가는 경우는 없다. 라고 하셨는데, 왜 그런지 이해를 못했습니다. ServerCore의 OnAcceptHandler는 콜백함수라서 콜백함수는 다른 스레드가 생겨나서 실행이 된다고 들었던 것 같은데, 그렇다면 두 스레드가 OnAcceptHandler에서 Session.Start()를 해버리면 OnRecvCompleted()메서드를 두 스레드가 동시에 실행할 경우가 생기지 않나요?