[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문
예를 들어 무적일때 피해를 입지 않게 한다면, static public bool isInvincibility; // 무적상태 public int hp =100 ; public int Hp { get { return hp1; } set {if(!isInvincibility) hp1 = value; } } 이렇게 설정할때, 자동 프로퍼티도 위와 같이 설정 할수 있을까요? public int hp { get; set; } = 100; 위 문장에서 set 부분 안에 저 무적 부분을 넣어보고 싶습니다.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 예제_3 { class Program { int a = 3; static void Main(string[] args) { int a; a = 1; //a=3.14F; char c = 'A'; string str = "abcd"; bool con = true; Console.WriteLine("a =" + a); Console.WriteLine("c =" + c); Console.WriteLine("str =" + str); Console.WriteLine("con =" + con); Func1(); } // 같은 이름이 있으면 내가 속한 블럭의 것이 우선! static private void Func1() { Console.WriteLine("a =" + a); } } } 이걸 똑같이 하는데 빌드 시작... 1>------ 빌드 시작: 프로젝트: 예제_3, 구성: Debug Any CPU ------ 1>D:\임상훈\C# 프로그래밍 기초\실습\예제_3\예제_3\Program.cs(29,39,29,40): error CS0120: static이 아닌 필드, 메서드 또는 속성 'Program.a'에 개체 참조가 필요합니다. ========== 빌드: 성공 0, 실패 1, 최신 0, 생략 0 ========== 빌드 실패가 뜨는 이유를 모르겠습니다.
[Adaptive Performance] Adaptive Performance is disabled via Settings. 테스트 플레이중에 자꾸 이 메세지가 나와서 거슬리는데요 에디트 - adaptive Performance에 들어가서 해결하려고했느데 Android Provider 체크박스는 체크가 되지않고 Adaptive Performance Provider Management error. Failure reason: Error Message: Unable to add package [ com.unity.adaptiveperformance.google.android ]: Cannot find a version of package [ com.unity.adaptiveperformance.google.android ] compatible with this Unity version (2021.3.16f1).. Error installing package 이런 오류만 발생합니다 삼성 안드로이드 프로바이더는 체크가 되서 체크를 하는데 그래도 같은 메세지가 출력됩니다. 이유가 무엇인가요??
BackgroundBlockSpawner 스크립트에서 프리팹을 생성하는 // 블록 생성 (원본 프리팹, 위치, 회전, 부모 Transform) GameObject clone = Instantiate(blockPrefab, position, Quaternion.identity, transform); 부분에서 마지막 부모 Transform 위치에 적은 transform 작성 이유를 모르겠습니다... 뭔가 프리팹이 생성 될 때, 어떤 부모 오브젝트의 자식으로 프리팹이 생성되는 것 같은데.. 정확한 설명 부탁드립니다.
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
안녕하세요 학습자료 다운로드 후 실행 관련해서 질문 드립니다. .csproj파일이 있는 클라이언트 폴더를 유니티로 실행 시키고, 게임 씬을 더블클릭 하고 실행했는데 작동이 되질 않더라구요. 보면 하이라키에 있는 인스턴스들이 보이질 않는데 매번 프로젝트를 실행할 때마다 하이라키를 추가를 해줘야 하나요??? 또 전체 흐름 로그를 한번 찍어보고 싶은데 어떤 식으로 찍어봐야 할지 모르겠습니다.
다만 Listener의 Init 부분에서 위 사진의 코드가 register개 만큼 쓰레드를 생성한다고 보면 맞을까요? 그리고 C++에서는 여러개의 Worker Thread가 GetQueuedCompletionStatus 로 이벤트 분기에 따라 send, recv, accept, connect 등을 처리해줬는데, 이 코드는 Accept만 멀티쓰레드로 처리하고 Send, Recv는 싱글쓰레드로 처리되는건가요?
"폴더 정리" 강의의 9:51초 화면에서는 유니티쨩의 모델을 hierachy로 뺀 후 playercontroller 스크립트 적용 후, 프리팹 폴더로 빼면서 프리팹을 만드는 화면이 나오는데, 제쪽에서는 유니티쨩 모델을 hierachy 창으로 끌어당기면 강의 화면처럼 inspector 창에 Model 이라는 표시 대신, 이미 프리팹이 적용된 것 처럼 나와 유니티쨩을 프리팹으로 만들려고 하면 prefab variant로만 만들 수 있다고 창이 표시됩니다. 분명 말씀하신대로 tank 프리팹과 유니티쨩 모델의 앞부분 박스 상자 아이콘은 다른데, 유니티쨩에게서 모델이라는 내용을 강의와는 다르게 찾아볼 수가 없습니다. 현재 22.2.16 버전을 사용중인데 버전이 올라가면서 해당 내용이 뭔가 수정된 부분이 있는걸까요?
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
제가 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#기반으로 돌아가는 웹을 작업중인데요 input 태그에 한글 작성시 '마지막 글자 밀림'오류와 '문자열 마무리'오류가 발생되어 혹시 해결 방법을 아시는 분이 있을까 하여 글 남깁니다..! 제발 도와주세요 감사합니다 !
[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일 때의 서버에서 이동 처리 방법이 궁금합니다! 또한 위처럼 순간이동되게 가는 것을 방지하는 법도 궁금합니다.. (스르륵 이동하게 처리하는 부분)