본문 바로가기

IndianPoker

[11] Battle Scene 턴 페이즈에서 사용할 TMP-Button들. 각 기능은 아직 만들지 않았다. 우선은 버튼만 만들고, 나중에 배치하자. 그 다음은 덱과 핸드, 사용할 Hand[0]의 카드 위치를 지정해놓자. 또, 카드들의 숫자와 이미지(Sprite)를 [CreateAssetMenu(fileName = "NewCardData")], ScriptableObject를 통해 데이터베이스처럼 만들어준다. 헷갈린 부분. Class 전체를 에디터에서 입력할 수 있게 받아오려면 SerializeField가 아니라 Serializable로 선언해야한다. [Serializable] 특성은 인스턴스를 직렬화하는 기능으로, MonoBehaviour로 선언한 클래스를 에디터에서 값을 수정할 수 있는 것처럼 아래 인스턴스 변수에 접근할 수 있게 .. 더보기
[10] 게임 구조 설계 겸 튜토리얼 장면 만들기 서버 제작이 잠시 보류된 상태니, 혼자서도 플레이 할 수 있도록 게임 구조를 만들어보자. 어차피 튜토리얼때문에 만들어야 한다. 우선, 게임은 게임 - 라운드 - 턴의 순서로 포함되어있다. 게임이 시작하면 사용할 덱과 카드들을 나눈다. 라운드가 시작하면 이번 라운드에 사용할 카드를 뽑는다. 이 카드가 사용이 끝나면 다음 카드를 뽑고 다음 라운드가 된다. 턴은 한 라운드에서 행동하는 사람이 바뀔 때마다(배팅을 진행할 때마다) 변화한다. 라운드마다 턴은 초기화된다. 그러니 우선적으로 필요한 함수는 게임 시작, 라운드 시작, 턴 교체에 대한 함수다. 이 셋을 만들어놓자. 게임 시작 public void StartGame() { InitGame(); } //게임 시작 전 초기화, 덱과 카드, 칩과 배팅 등을 초기.. 더보기
[09] Coroutine과 Thread의 차이점 (공부 후 재작성) [08]에서 코루틴을 통해 비동기적 메소드로 서버를 돌리려고 시도했지만, 이런 저런 이유들로 안됐다. 결국은 Accept -> BeginAccept로 가는 방식을 사용해서 해결하기로 마음먹었지만, 의문이 생겼다. Coroutine도, Thread도 비동기적으로 실행되는 것처럼 보이는데, 왜 둘은 다른가? -> 둘 다 동시 실행처럼 보이지만, 사실 Coroutine는 스케쥴링(순서 알잘딱)에 의한 지연실행에 불과하기 때문. 매 프레임을 기준으로 코루틴을 확인하는 과정을 해줄 뿐이다. 그래서 만약 코루틴의 과정에 문제가 생긴다면, 메인 동작도 영향을 받는다.(결국은 순차적 실행이기 때문에, 앞의 작업이 완료되지 않으면 뒤로 가지 못한다.) -> 참고자료 https://planek.tistory.com/36 .. 더보기
[08] UI와 Scene, 스크립트 정리 + 서버 의문 게임을 플레이 할 방을 들어가는 것까지의 게임 구조도를 정리해보았다. 현재 구현된 것은 Loading에서 Home으로 가는 것, 종료, 서버 접속까지이다. 기존에 만들어놓은 Scene과 기능들이 따로 놀고 있는 느낌이 있어, 위의 구조도를 기반으로 재정렬하자. Loading에서 플레이어의 데이터를 검사하고, 없다면 새로운 계정을 생성한다. 이 과정은 데이터베이스가 만들어지고 나서 구현할 문제이므로, 일단은 플레이할 때마다 임시 프로필을 부여받아 Home에 접속하는 것으로 하자. 그 이후 Home에서 서버 접속을 시도한다. 처음 로딩 화면이다. 지금은 다음 Scene을 로딩하는 기능밖에 없지만, 나중에 플레이어의 데이터를 불러오고, 데이터가 없다면 플레이어 데이터를 새로 생성하는 장면이다. 그 다음은 Ho.. 더보기
[07] 채팅창 UI 만들기, TMP로 한글 쓰기 플레이어가 입력하면 서버의 모든 이용자가 메시지를 볼 수 있는 채팅창을 만들어보자. 기본적인 구성은 위의 사진처럼 Chat이 올라오고, 채팅창의 아래부분을 누르면 채팅을 입력할 수 있는 InputField가 등장하는 구조다. 이제 채팅을 입력하고, 위에 올리는 작업을 시행해야 하나... 그 전에 해결해야 할 문제가 있다. 바로 한글이 쳐지지 않는다는 것. 이 상태로 무언가를 만들어도, 한글로 된 내용은 전부 빈 네모로 바뀔 뿐. 그건 폰트가 한글을 지원해주지 않기 때문이다. 따라서, 우리는 유니티에 TMP에서 쓸 수 있는 한글 폰트를 설정할 필요가 있다. 우선 한글을 지원하는 폰트를 다운받아, TextMeshPro의 Fonts 폴더에 집어넣어주자. 작성자는 넥슨에서 지원하는 메이플스토리 폰트를 사용했다... 더보기
[06] TCP, 클라이언트 만들기 [05]에서 만든 서버 쪽 기초 내용은 아래와 같다. using UnityEngine; using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; public class TCPTutorial : MonoBehaviour { public const int BUFFER_SIZE = 1024; private Socket serverSocket; private IPAddress ipaddress; private string ipaddressStr; private int port; private IPEndPoint endpoint; //Socket -> Bind -> listen -> acce.. 더보기
[05] Thread, Handle Client [04]에서 HandleClient(Socket clientSocket)에 대해 다룬다고 이야기했다. 이 쓰레드로 클라이언트와 서버 간 통신이 이루어지는데, 통신이 무엇일까? 서로 정보를 주고 받는 일이다. 이해를 하기 쉽게 과정을 좀 더 뜯어본다면, 버퍼를 통해 통신이 이루어진다. 매 순간순간, 한 글자 한 글자를 입력할 때마다 클라이언트가 서버로 보내고 처리하는 것은 비효율적이다. 묶음이 필요하다. Client가 정보를 보내면(write), Send Buffer에 가서 정보가 쌓이게 된다. 그 쌓인 정보들은 다시 서버가 읽을 대기목록인 Receive Buffer에 쌓이게되고, Server가 그 버퍼 안의 내용물을 읽는 것이다. (서버에서 클라이언트로 정보를 보내는 과정은 반대.) 그림에서 느껴지듯, .. 더보기
[04] TCP 서버, Thread [03]과 이어집니다. serverSocket.Bind(endPoint); 을 사용해서 serverSocket과 endPoint를 연결해줍시다. 이제 [03]에서 말했던 서버의 Socket -> Bind -> listen -> accept -> receive -> send -> receive -> close 과정에서 Bind까지를 끝냈습니다. Listen 메소드를 만들어봅시다. private void ListenSocket() { serverSocket.Listen(5); // 대기 큐 크기를 지정 Console.WriteLine("Server started. Waiting for connections..."); Socket clientSocket = serverSocket.Accept(); } List.. 더보기