안녕하세요, RecvBuffer 강의중에서 //읽을 수 있는 유효한 데이터의 범위 public ArraySegment<byte> ReadSegment { get { return new ArraySegment<byte>(_buffer.Array, _buffer.Offset + _readPos, DataSize);} } //사용가능한, 비어있는 범위 public ArraySegment<byte> WriteSegment { get { return new ArraySegment<byte>(_buffer.Array, _buffer.Offset + _writePos, FreeSize); } } 위와 같이 segment 프로퍼티를 설정하였는데, 중간 인자로 그냥 readPos를 넣지 않고 buffer.Offset + readPos 로 계산한 이유를 모르겠습니다. 현재 저의 생각으로는 buffer.Offset은 결국 언제나 0이지 않나? 입니다. 코드를 보았을 때 offset을 조작하거나 건드리는 코드는 아직 현재강의(RecvBuffer)까지는 없고, 나중에라도 _readPos와 DataSize가 결국 segment범위를 바꿔주니 이 offset을 건들일 필요는 없다고 생각이 드는 상태입니다. 또한, 만약 offset을 변경시키는 경우가 있더라도 offset+readpos 하면 offset이 0이 아닌경우 readpos에 맞지않는곳이 시작위치가 될텐데 왜 offset을 더하는건지 이해가 되지 않습니다. 따라서 offset을 더한 이유가 궁금합니다!
안녕하세요, RecvBuffer 클래스를 작성하는 강의에서, clean()함수를 작성하실 때 강사님께서는 이렇게 작성하셨는데, 혹시 아래와 같이 Array.Copy(ReadSegment.Array, 0, _buffer.Array, 0, DataSize); 이렇게 작성해도 똑같은 결과가 나오려나요? 혹은 나중에 다른상황에서 이렇게 작성하면 다르게 동작한다던지 그런 문제가 있을까요? 위에 적용된 ReadSegment범위를 사용하지 않는 이유가 뭔지 궁금합니다. public void Clean() { int dataSize = DataSize; if (dataSize == 0) { _readPos = 0; _writePos = 0; } else { Array.Copy(ReadSegment.Array, 0, _buffer.Array, 0, DataSize); _readPos = 0; _writePos = dataSize; } }
manager public class Managers : MonoBehaviour { static Managers s_Instance; //유일성이 보장된다 public static Managers instance { get { Init(); return s_Instance; } } // 유일한 매니저를 갖고온다 InputManager _input = new InputManager(); public static InputManager input { get { return instance._input; } } // Start is called before the first frame update void Start() { Init(); } // Update is called once per frame void Update() { _input.OnUpdate(); } static void Init() { if (s_Instance == null) { GameObject go = GameObject.Find("@Managers"); if (go == null) { go = new GameObject { name = "@Managers" }; go.AddComponent<Managers>(); } DontDestroyOnLoad(go); s_Instance = go.GetComponent<Managers>(); } } } ================================== playercontroller.cs public class PlayerController : MonoBehaviour { [SerializeField] float _speed = 10.0f; // Start is called before the first frame update void Start() { Managers.input.KeyAction -= OnKeyboard; //실수 방지용으로 미리 한번 -함 Managers.input.KeyAction += OnKeyboard; } // Update is called once per frame void Update() { } void OnKeyboard() { if (Input.GetKey(KeyCode.W)) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f); transform.position += Vector3.forward Time.deltaTime _speed; } if (Input.GetKey(KeyCode.S)) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f); transform.position += Vector3.back Time.deltaTime _speed; } if (Input.GetKey(KeyCode.A)) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f); transform.position += Vector3.left Time.deltaTime _speed; } if (Input.GetKey(KeyCode.D)) { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f); transform.position += Vector3.right Time.deltaTime _speed; } } } ================================== public class InputManager { public Action KeyAction = null; public void OnUpdate() { if (Input.anyKey == false) return; if (KeyAction != null) KeyAction.Invoke(); } } ================================== player.cs public class Player : MonoBehaviour { // Start is called before the first frame update void Start() { Managers mg = Managers.instance; } // Update is called once per frame void Update() { } } 지금 unitychan 오브잭트에 playercontroller 컴포넌트를 inspector창에다 추가한뒤에 실행을 하는데 input값을 입력받을떄마다 어떤식으로 작동이되는지 순서가 이해가 안가요 playercontroller 에 update()에 아무것도 없는데 지속적으로 어떻게 key값을 받는지 궁금해요 start()는 1회실행되는 함수인데 player.cs도 지금 존재 이유가 유일한 manager 컴포넌트를 쓰게하기 위해서 만들었는데[ 점점 갈수록 어렵네요
안녕하세요, connector와 listener변수에서 static 차이가 일어나는 이유에 대해 질문드리고자 합니다. server 코드의 listener는 아래와 같이 static으로 정의하셨는데, (그리고 저 _obj는 왜 있는건지, 그냥 지워도 되는걸까요?) static object _obj = new object(); static Listener _listener = new Listener(); client코드의 connector는 그냥 static없이 Connector connector = new Connector(); 이렇게 그냥 변수로 지정하신 이유가 궁금합니다.
안녕하세요 고박사님. 제가 이 강의에서 모든 부분 다 이해가 갑니다. 근데 제가 게임수학 부분은 안해봐서 그런지, 삼각함수 쪽에서 좀 막혀서 따로 공부했는데, 타겟에 핀 배치할 때 왜 굳이 래디안을 구해야하는 지 이해가 잘 안가서 여쭤봅니다. 실험으로 래디안 식 없이 돌려보니 핀 머리는 잘 배치가 되는데 막대기 부분의 위치와 로테이션이 잘못 배치돼더군요. 꼭 있어야하는 식인 것 같은데, 왜 그런지 이해가 안갑니다. 이 부분만 설명 한번만 부탁드려도 될까요?
public ArraySegment<byte> ReadSegment { get { return null; } } public ArraySegment<byte> WriteSegment { get { return null; } } 심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태 오류 CS0037 'ArraySegment<byte>'은(는) null을 허용하지 않는 값 형식이므로 null을 이 형식으로 변환할 수 없습니다. ServerCore 저는 null을 넣을때 오류가 뜨는데 무슨 이유일까요?
안녕하세요! 캐쥬얼 싱글 게임을 만드려고 하는 뉴비입니다. 강의수강중에 서버에 관련한 질문을 보다가 저도 비슷한 궁금증이 있어서 댓글 남깁니다. 싱글 게임에는 굳이 서버가 필요 없다고 하셨는데요 그래도 플레이팹이나 파이어베이스같은 서버를 붙히고 싶습니다! 1. 유저 데이터를 서버에서 받아서 여러 기기에서 플레이해도 설정값 등등을 불러올수 있도록 2. 주기적으로 클라이언트의 데이터 값과 서버의 데이터값을 비교해서 동기화 3. 인게임 재화를 이용한 상자에서 나오는 아이템들을 처리하는 함수등등 중요한 데이터를 서버에서 호출 4. 우편함 시스템 등등 위와 같은 기능들을 서버로 구현해서 보안도 향상시키고 일부 편의 기능들도 추가하고싶어요. 그런데 제가 서버에 대한 지식이 전무하다는게 문제입니다 : ( 그래서 지금 당장 서버공부 부터 시작을 해야할까요? 게임을 만들다가 추후에 서버를 붙히려고 하면 기존의 코드를 전부 수정해야한다던지 하는 일이 일어나지는 않을까요..? (이부분이 제일 궁금합니다) 배움의 순서가 어느것이 맞는 것인지 게임을 만들면서 추후에 서버를 고려해도 괜찮은지 루키스님의 의견 부탁드립니다!
Session#2 강의 시작부분에 설명해주신 내용에서, SEssion의 receive는 OnRecvCompleted()메서드에 여러 스레드가 동시다발적으로 들어가는 경우는 없다. 라고 하셨는데, 왜 그런지 이해를 못했습니다. ServerCore의 OnAcceptHandler는 콜백함수라서 콜백함수는 다른 스레드가 생겨나서 실행이 된다고 들었던 것 같은데, 그렇다면 두 스레드가 OnAcceptHandler에서 Session.Start()를 해버리면 OnRecvCompleted()메서드를 두 스레드가 동시에 실행할 경우가 생기지 않나요?
학습중에 클래스를 제네릭으로 받으면 어떻게 될까 궁금해 한번 받아봤습니다! 우선 필요한 정보를 받아올때 json 파일마다 역직렬화 & 직렬화 용도의 클래스가 다르기 때문에 해당 부분을 public IEnumerator CoDownLoadJsonData<T>(string URL) where T : class { UnityWebRequest request = UnityWebRequest.Get(URL); yield return request.SendWebRequest(); // 에러 발생 시 if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { Debug.Log(request.error); } // 에러 없을 시 else { // S3의 JSON 파일 읽어와서 넣어주기 T[] jsonDatas = JsonConvert.DeserializeObject<T[]>(request.downloadHandler.text); // 그 뒤 값 처리 해주는 부분 foreach (T jsonData in jsonDatas) { // TEMP Debug.Log(무슨 값을 넣어야 할까요); } } } 이렇게 짜봤습니다. 위의 함수를 실행 할 때 넣은 T 값은 public class JsonData { public string name; public int coin; public int ruby; } JsonData라는 클래스 입니다. 그리고 다운로드 받은 json 데이터의 name 값을 보기위해 '무슨 값을 넣어야 할까요' 부분에 jsonData.name을 쳐보았지만 타입이 제네릭이라 받기전까지 name이 있나 없나를 알 수 없기 때문에 당연히 해당 코드는 에러가 났습니다. 이러면 파싱 받을 json 데이터 마다의 클래스를 따로 분기해서 처리해줘야 한다는 말인데 제네릭 타입을 이용하여 루키스님 처럼 우아?하게 코드를 짜보고 싶은 생각이 드네요. 방법을 못 찼겠어서 질문드립니다!! 현재 저의 머리로는 제네릭으로 만든후 안에 조건문을 추가해서 as 로 파싱되면 그쪽으로 처리하는 분기문을 만드는게 한계인거 같네요 ㅠㅠ 값은 정상적으로 받아와집니다만 브레이크 포인트를 통해서 값을 확인하는 것이 아니면 확인이 안되네요 ㅠㅠ
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문
그 저는 if문 말고 switch문으로 하여 switch(input) case"1": Fight(ref player, ref monster break; case"2": randExit(ref player,ref monster); break; 2번 선택 시 static void randExit(ref Player player, ref Monster monster) { Ranom rand = new Random(); int randValue = rand.Next (1,101); if (randValue <= 33) { Console.WriteLine("탈출 성공"); EnterGame(ref player); } else { Console.WriteLine("탈출 실패"); Fight(ref player, ref monster); } 이렇게 했는데 이렇게하면 스택 영역에 또 함수를 호출하는 것으로 부담을 주는 걸까요? randExit 함수를 넣음으로써 뭔가 경로를 추가한 느낌이라서 더 안좋은지 궁금합니다. ( 심각할 정도의 의구심이 드는건 아니고 살짝 갖게 된 의문점입니다)
안녕하세요 선생님, 제가 새 프로젝트를 만들면서 이름과 위치를 정하고 다음으로 넘어갔더니 대상 프레임워크에 .NET Core 3.1 (지원하지 않음) 이라고 나옵니다. visualstudio installer에서 제가 보기에 c#에 관련된 것은 다 설치한 상태인데 더 설치해야 하는 것이 있는걸까요?
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문
struct 변수들을 개방을 할때 public struct Player {int hp; int attack;} struct Player{public int hp; public int attack;} 둘다 같은 의미인줄 알았는데 1번을 하면 오류가 나고 2번처럼 변수 하나하나에 퍼블릭을 넣어야하는게 묶음 전체를 개방한다도 될거같은데 왜 안되는지 이유를 여쭤봐도되나요? 1번 처럼 구조체 자체에 퍼블릭을 넣는 경우도 있나요? 혹시 객체파트로 넘어갈때 쓰이는 것일까요?