월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
위치 동기화 기능구현 질문이 있습니다
선생님 안녕하세요 서버강의를 듣고 이를 응용하여 3축 좌표계에서 플레이어가 접속하면 프리팹을 생성하고, 트랜스폼 정보와 애니메이션 정보를 동기화하는 서버를 구현하였습니다.플레이어가 접속하면 생성되는 프리팹은 언리얼의 HasAuthority와 같이 로컬 클라이언트의 소유가 되어 클라이언트만 자신의 위치를 브로드캐스트하면 다른 플레어들은 위치를 수신하여 손쉽게 구현이 가능했습니다!하지만 월드에 미리 배치되어있는 무버블 오브젝트들은 어떻게 동기화를 해야하는지 궁금합니다. 누구의 소유도 아닌 공공(?)의 오브젝트들은 누가 동기화 패킷을 보내줘야하는지 어렵습니다 ㅜㅜ조금 더 설명을 하면, 특정 조건에 함수가 호출되어 움직이는 기능을 수행하는경우는 RPC로 원격지 클라이언트에서 함수를 호출할 수 있게 구현하였습니다.하지만 미리 씬에 배치되어있는 Sphere 오브젝트를 플레이어가 움직이면서 밀어RigidBody 연산으로 자연스러운 움직임을 어떻게 동기화해야하는지 잘 모르겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
학습자료 실행 관련 문의
안녕하세요 학습자료 다운로드 후 실행 관련해서 질문 드립니다..csproj파일이 있는 클라이언트 폴더를 유니티로 실행 시키고, 게임 씬을 더블클릭 하고 실행했는데 작동이 되질 않더라구요. 보면 하이라키에 있는 인스턴스들이 보이질 않는데 매번 프로젝트를 실행할 때마다 하이라키를 추가를 해줘야 하나요???또 전체 흐름 로그를 한번 찍어보고 싶은데 어떤 식으로 찍어봐야 할지 모르겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
Tilemap.cellBounds에 관련해서 질문 있습니다.
제가 Tilemap을 아래와 같이 만들어 놨는데요,cellBounds에 break point를 잡아서 디버깅을 해보니 x.Max = 20, y.Max = 9가 나오더라구요. (제가 찍은 tilemap을 일일히 하나하나 세보니 x의 최대 좌표는 19고 y는 8인데도 말이죠.)그렇다면 위 코드와 같이 반복문을 돌면 타일이 찍혀있지 않는 y = 9, x = 20 일 때도 반복문을 도니까 제가 만든 맵보다 가로 세로가 한 줄씩 늘어나게 출력됩니다. (아래 사진처럼 맨 윗줄과 오른쪽 줄에 0이 출력되서 나옵니다.)제가 생각하기에는 아래와 같이 코드를 짜야 알맞은xMin, xMax, yMin, yMax값과 map이 출력될 거 같은데 혹시 제가 틀린건가요?using (var writer = File.CreateText($"Assets/Resources/Map/{go.name}.txt")) { writer.WriteLine(tmBase.cellBounds.xMin); writer.WriteLine(tmBase.cellBounds.xMax - 1); writer.WriteLine(tmBase.cellBounds.yMin); writer.WriteLine(tmBase.cellBounds.yMax - 1); for (int y = tmBase.cellBounds.yMax - 1; y >= tmBase.cellBounds.yMin; y--) { for (int x = tmBase.cellBounds.xMin; x < tmBase.cellBounds.xMax; x++) { TileBase tile = tm.GetTile(new Vector3Int(x, y, 0)); if (tile != null) writer.Write("1"); else writer.Write("0"); } writer.WriteLine(); } }
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
화살 쏘는 것을 처리하는 방식
안녕하세요 루키스님!제가 루키스님이 강의중 만드신 게임에서 쓰이는 좌표를 float으로 바꾸고 화살이 이동하는 방식을 수정하였습니다.(저는 화살이 아니라 기본 동그라미 이미지의 총알로 사용해봤습니다)수정 내용은 화살 이동 로직을 처리하는 방법입니다. 기존 로직은 서버에서 GetFrontCellPos 함수를 이용하여 서버에서 이동된 좌표를 클라로 알려줘 이동되는 것으로 알고 있습니다. 클라에서는 UpdateMoving를 통해 움직이고 있구요!GetFrontCellPos 함수를 활용하여 서버에서 화살을 움직이기에는 좌표 단위가 Int가 아니라 float이니 어떻게 해결 해야할지 고민을 하다가 생각난 방법이 있습니다.화살을 쏜 후 유니티의 update 문에서 60fps로 서버에 화살이 이동했다는 것을 가르쳐준 후 브로드캐스팅 되게 했습니다. 그 후 서버에서는 받은 패킷에 따라 브로드 캐스팅하게 핸들링 해줬구요.이제 2명을 접속시키고 화살을 쏴보니 패킷이 밀려서 그런지 몰라도 쐈던 자리로 다시 롤백되는 현상을 발견했습니다(배그에서 트레이서 되는 느낌)60fps가 너무 자주 요청하는 건가 싶어서 15fps로 돌리니 클라 화면에서 내가 쏜 총알은 똑같이 롤백되면서 총알이 나가지만 다른 Player가 쏜 총알은 롤백이 되지 않았습니다. 하지만 이동된다기 보다는 순간이동 하는 것 처럼 보이기 시작했습니다.몇가지 실험을 해보니 혼자 접속중일때는 총알이 롤백현상이 일어나지 않고 곧게 잘 날아가는 것을 확인할 수 있으나 인원수가 한 명 늘어나는 순간부터 총알의 롤백 현상이 생기는 것을 확인했습니다. 브로드 캐스팅의 연산량이 늘어나서 패킷이 밀리는 것이 원인인 것 같습니다.C_SkillMove, S_SkiilMove 라는 패킷을 새로 파주고 실행했습니다. message C_SkillMove{int32 objectId = 1;PositionInfo posInfo = 2;}message S_SkillMove{int32 objectId = 1;PositionInfo posInfo = 2;}클라의 업데이트 문에선if (Time.frameCount % 15== 0){C_SkillMove skillMovePacket = new C_SkillMove();PosInfo.PosX = transform.position.x;PosInfo.PosY = transform.position.y;skillMovePacket.PosInfo = PosInfo;skillMovePacket.ObjectId = Id;Managers.Network.Send(skillMovePacket);} 이런 코드로 움직입니다. 서버에선public static void C_SkillMoveHandler(PacketSession session, IMessage packet){C_SkillMove skillMovePacket = packet as C_SkillMove;ClientSession clientSession = session as ClientSession;Arrow arrow= ObjectManager.Instance.Find<Arrow >(skillMovePacket.ObjectId);if (arrow== null)return;GameRoom room = arrow.Room;if (room == null)return;room.HandleSkillMove(arrow, skillMovePacket);} 이런식으로 핸들링 하고 HandleSkillMove 함수는 public void HandleSkillMove(Arrow arrow, C_SkillMove skillMovePacket){if (arrow == null)return;lock (_lock){ObjectInfo info = arrow.Info;info.PosInfo = skillMovePacket.PosInfo;S_Move resMovePacket = new S_Move();resMovePacket.ObjectId = arrow.Info.ObjectId;resMovePacket.PosInfo = skillMovePacket.PosInfo;Broadcast(resMovePacket);}}이런 로직으로 움직입니다.float일 때의 서버에서 이동 처리 방법이 궁금합니다! 또한 위처럼 순간이동되게 가는 것을 방지하는 법도 궁금합니다.. (스르륵 이동하게 처리하는 부분)
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
이동 동기화 중에서 딜레이후 동기화 처리
실무에 가깝게 적용할만한 캐릭터간 이동 동기화 중에서 딜레이후 동기화 처리에 대한 참고할만한 이론이나 문서 같은것이 있을까요? 게임 장르는 존 방식이고 한 방에 최대 100명 이하? 정도 될것 같은데요환경은 모바일이고요 약.. 서버에서 1초에 4~8번 정도(정확히 아직 1초에 몇번 보내는지는 모릅니다)의 이동관련 패킷을 TCP나 UDP로 보낸다고 가정할 경우 일정 시간 이동 관련 위치 값을 수집해서 보간 처리 해볼까 하는데 언리얼 데디케이트 서버에서 어떻게 해야 할지 좀 막막한것 같은데 관련된 문서나 방식등이 있을까요?루키스님 강의 중 C++ 쪽 서버강의에서 이미 강의는 어느정도 듣긴했지만 이동 관련된것이 없는것 같아서 질문 남깁니다답변좀 부탁드리겠습니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
nupkg to dll 방법 공유합니다
nuget package를 dll파일로 변환하는 방법 공유합니다저도 몰라서 한참 헤맸기 때문에 공유하면 좋을것 같아서요!https://youtu.be/JgkPoxeb714이 방법대로 하면 됩니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
맥 OnRecvCompleted transferredBytes 에러
구글 프로토 버퍼 연동을 하던중서버에서는 패킷을 보내도 클라쪽에서 recvArgs 는 받은 바이트배열이 하나도 없는데 구글 프로토버프 패킷 형식이나 그냥 바이트 배열을 보내봐도 똑같습니다.분명히 socketError == SocketError.Success인데 받은 바이트가 없다는게 이해가 안됩니다ㅠ혹시 왜 그런지 알 수 있을까요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
AI를 별도의 클래스로 관리한다는 말의 의미
안녕하세요 강사님! 강의를 듣다가 정확한 의미파악을 못해서 질문을 하게 되었습니다.보통의 게임에서는 AI를 별도의 클래스로 관리한다고 하셨는데 AI라는 단위가 정확히 뭔지 모르겠어서 질문을 남기게 되었어요.예를들어 지금 강의속 프로젝트같은 경우 UpdateIdle함수 / UpdateMoving함수 / UpdateSill함수 / UpdateDead함수가 다 따로따로 별도의 AI인건지, 아니면 위에 열거한 모든 함수가 하나의 AI로 관리된다는 의미인지 정확히 이해를 못했습니다 ㅠㅠ 어느쪽으로 이야기하신걸까요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
Unity엔진의 GetComponent 기능
CreatureController cc = go.GetComponent<CreatureController>();if (cc != null)cc.OnDamaged();//go는 MonsterController를 가지고 있음에서 CreatureController를 상속박은 MonsterController의 오버라이드한 함수가 실행되는데CreatureController cc = go.GetComponent<CreatureController>();는CreatureController cc = new MonsterController;와 같은 기능이기 때문에 그런걸까요?(UNITY GetComponent의 기능인가?)만약 그렇다면 분명 GetComponent로 CreatureController를 불렀는데 어떻게 MonsterController가 리턴되었는지도 궁금합니다 GetComponent의 UNITY 내부 엔진 기능인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
이동 동기화 - float
강의에선 한칸씩 이동을 하는데 저는 float 단위로 이동하게 하고 싶어 클라이언트에서 플레이어의 실제 position이 바뀌는 부분에 서버에 패킷을 보냈습니다!서버쪽 콘솔창에는 패킷이 온전히 받아와주기 주고 받는게 돼고 있습니다. 클라이언트에도 브레이크 포인트를 찍어보니 제대로 값이 들어오고 있구요!패킷에서 posX, posY도 docs를 참고하여 float으로 변수 타입을 바꿔줬습니다!클라이언트에서도 실제 이동이 일어나는 부분에서 값을 바꿔주었고 이동 패킷 또한 서버에 쏴주었는데 화면에는 이동의 동기화가 이루어지지 않습니다 ㅠㅠ 이유가 뭘까요?이정도 자료만으로 알기 힘드실 것 같지만 막혀서 질문드립니다..!클라쪽 핸들러 코드도 강의와 똑같습니다!float 이동이나 int 단위 이동이나 이론상 변수 타입만 다르고 돼야하는 게 아닌가가 저의 생각입니다! 답변 부탁드리겠습니다!ㅠㅠ
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
멀티환경일때와 싱글환경일때 구현 차이 궁금증이 있습니다.
안녕하세요 선생님! 강의를 듣다 질문이 생겼는데요.전체적으로 싱글게임처럼 진행되게 하고싶은데 레벨업 시스템은 만들어 그걸 서버와DB에서 관리하고 싶을때 게임룸이나 몬스터와 관련해 질문이 생겨서요.위와 같은 경우는 몬스터, 플레이어간의 동기화 부분만 제외하고 강의에서 구현한 것처럼 똑같은 방식으로 구현하면 되는걸까요??
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
클라에서 build를 통해 만든 exe파일에서 이동동기화가 이루어지지 않습니다
안녕하세요 강사님! 다름이 아니라 강의를 따라해보고 그 뒤에 거의 흡사하게 한 번더 다른 파일에서 코드를 구현해보고 있습니다.그런데 서버에서 클라에 패킷보내는것까진 제대로 작동하는데(좌표확인까지됨) 클라에서 실제로 테스트를 위해 실행했을때 실질적인 플레이어캐릭터가 좌표 인식을 제대로 못하는 문제가 있습니다.구체적으로 첫번째클라를 실행하고 플레이어이동시키고잇는도중 두번째클라가 실행되면 두번째클라에서도 첫번째클라플레이어 이동이 제대로 동기화되어보이는데이후 두번째클라창으로 옮겨가서 플레이어를 이동시키면 첫번째클라창에서 타플레이어좌표이동이 플레이어오브젝트에 반영되지않고 방향과 상태만 반영됩니다. 이후 첫번째클라창으로 옮겨가 플레이어를 이동시키면 두번째클라창에서도 타플레이어좌표이동이 되지 않습니다. 와중에 서버에서 클라쪽에 패킷전송은 잘되고 있습니다.게다가 타플레이어가 실제로 이동한좌표로 가려고하면 충돌인식까진되는데 화면엔 타플레이어가 이동하기전 있던곳에 그대로 서있습니다이경우엔 보통 어떤부분이 문제인걸까요?ㅜㅜ+) break point 걸어놓고 유니티에서 확인해봤는데 유니티에서 실행하면 정상적으로 이동동기화 되는데 build를 해서 만든 exe파일에선 위와 같은 현상이 일어나며 적용이 안됩니다...
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
30분경에 말씀하신 구현방법을 다루시는지 궁금합니다.
안녕하세요 강사님30분경에 '실질적으로 지금보다 좀 더 복잡한 MMO가 되면 불러와야 할 정보들을 클라에게 먼저 알려준 다음 클라에서 모든 정보 불러오기가 끝났으면 서버쪽에 준비됐다고 ok패킷을 날리게 되고 ok패킷을 받고나서야 서버쪽에서 게임에 입장 시킨다고 하시면서 여기까지는 구현하지 않을거라고 하셨는데 해당 내용이 나중에 강의중에(다른파트에서라도) 나오는지 궁금합니다!혹시 강의중에 해당 내용이 없다면 구글링 검색어를 뭘로 하면 좋을지 알려주시면 감사하겠습니다!
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
배치파일을 실행하려고 하니 오류가 뜹니다
이렇게 뜨는데 어떻게해야할까요..?ㅠㅠ
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
충돌처리 질문
안녕하세요 강사님 강사님 강의를 듣고 IOCP서버와 유니티 클라이언트로 3D rpg게임을 제작하고 있습니다.충돌처리 같은경우 유니티에서 제공하는 boxcollider를 써서 충돌처리를 구현하는 방법을 사용해도 되나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
게임룸에 관한 질문입니다.
안녕하세요.강의를 보면서 fps를 주제로 포트폴리오 준비를 하고있는 도중에 궁금한 것이 있어서 질문드립니다. 유니티 데디케이트 서버? 로제작할 예정입니다.fps게임에서 여러개의 그룹, 방을 가지고 있는데 서버에서는 이 방마다 각각의 맵을 생성한뒤 가지고 있나요?다른 필요한 정보들은 검색으로 방향을 찾았는데 이러한것은 어떻게 검색해야하는지 감이 안잡히네요.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
몬스터 데미지 처리 방식 질문입니다.
이번 프로젝트에서는 화살에 대한 충돌 정보를 콜라이더를 통해서 하는게 아닌 매니저에서 List에 담긴 적 오브젝트에 위치 정보와 화살에 대한 위치 정보를 비교해서 해당 위치에 적 오브젝트가 존재할 경우 데미지를 처리하는 방식으로 로직을 구현하신 이유가 궁금해서 질문 남깁니다.현재 프로젝트에서 충돌 판정을 위해 List에 등록된 모든 object들의 위치 정보를 대조하는 방식으로 구현이 되어있는데, 대부분에 2D 온라인 게임들은 이런 방식으로 로직을 구성하는 건가요? 진행중인 프로젝트와 유사한 게임으로 예시를 들어주신 바람의나라, 리니지와 같은 게임 한정으로 이렇게 로직을 구성하는 건가요?개인적인 생각인데, List로 적 오브젝트를 관리하게 될 경우 적 오브젝트 수가 늘어나 생성,파괴,충돌, 이동이 수시로 일어날 경우 각 정보를 클라이언트들에게 뿌려주기 위해서 서버에 과부화가 있을 거 같은데, 이를 보완하는 방식이 있는지 혹은 List 말고 다른 방식이 존재하는지 궁금합니다 항상 좋은 강의 감사합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
protobuf를 쓰지않고 패킷을 만들경우
한번은 직접 패킷을 다루는걸 해보려고 하는데repeated PlayerInfo players부분은 리스트처럼 가변크기 데이터로는 못보내고고정크기 배열로 패킷을 만들어야 하는게 맞을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
json파일 관련 질문
안녕하세요!이번 강의를 다 듣고 npc대화 기능을 추가하려고json파일에 npc의 대사를 넣고client에서 보관하려고 json파일을 파싱하고 있었는데요,textAsset은 잘 가져 오는데, makeDict()의 결과는 항상 null입니다ㅜㅜ(Dictionary<int,Chat> <-- Chat이 Google.Protobuf.Protocol에서 정의되서 안되는 걸까요?)대소문자 때문인가 해서 이리저리 바꿔봐도 안됩니다,,왜 그런지 알 수 있을까요? 감사합니다:)
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
두번째 세션부터 entergame 패킷이 보내지지않습니다.
Part4를 베이스로 삼아 간단한 동기화만 구현을 해보려고 해보는 중입니다. 문제가 되는 것은 처음으로 들어온 세션은 EnterGame 패킷과 Spawn 패킷을 모두 받는 반면에 두 번째로 들어온 세션은 Enter패킷이 들어오지않습니다... 상황을 정리하자면첫번째 세션: MyPlayer생성 O, other Player 생성 O두번째 세션: MyPlayer생성 X, other Player 생성 X로그를 찍어보니 두번째 세션에 EnterGame Handler가 작동을 하지 않더군요... 혹시하는 마음에 질문해봅니다.EnterGamepublic override void EnterGame(GameObject gameObject) { if (gameObject == null) return; if (gameObject.ObjectType == GameObjectType.Player) { Player player = gameObject as Player; _players.Add(gameObject.Id, player); player.Room = this; // 본인한테 정보 전송 { S_EnterGame enterPacket = new S_EnterGame(); enterPacket.Player = player.Info; player.Session.Send(enterPacket); S_Spawn spawnPacket = new S_Spawn(); foreach (Player p in _players.Values) { if (player != p) spawnPacket.Objects.Add(p.Info); } player.Session.Send(spawnPacket); } } // 타인한테 정보 전송 { S_Spawn spawnPacket = new S_Spawn(); spawnPacket.Objects.Add(gameObject.Info); foreach (Player p in _players.Values) { if (p.Id != gameObject.Id) p.Session.Send(spawnPacket); } } }