// ---------------------------------------------------------------- // // 패킷 수신 함수]. // 동기 대기 패킷 수신. public void OnReceiveSyncPacket(int node, PacketId id, byte[] data) { Debug.Log("[CLIENT]OnReceiveSyncPacket"); GameSyncPacket packet = new GameSyncPacket(data); GameSyncInfo sync = packet.GetPacket(); GlobalParam.get().seed = sync.seed; // 초기 장비를 보존한다. for (int i = 0; i < sync.items.Length; ++i) { CharEquipment equip = sync.items[i]; GlobalParam.get().shot_type[equip.globalId] = (SHOT_TYPE)equip.shotType; this.select_done_players[equip.globalId] = true; Debug.Log("[CLIENT] AccountID:" + equip.globalId + " ShotType:" + equip.shotType); } // 응답이 있는 쿼리를 검색. string account_id = this.player.control.getAccountID(); QuerySelectFinish query = QueryManager.get().findQuery <QuerySelectFinish>(x => x.account_id == account_id); if (query != null) { Debug.Log("[CLIENT]QuerySelectDone done"); query.set_done(true); query.set_success(true); } Debug.Log("[CLIENT]Recv seed:" + sync.seed); }
// ================================================================ // public void OnReceiveEquipmentPacket(int node, PacketId id, byte[] data) { EquipmentPacket packet = new EquipmentPacket(data); CharEquipment equip = packet.GetPacket(); Debug.Log("[SERVER] Receive equipment packet [Account:" + equip.globalId + "][Shot:" + equip.shotType + "]"); // 캐릭터의 장비를 보존. if (m_equips.ContainsKey(equip.globalId)) { m_equips[equip.globalId] = equip.shotType; } else { m_equips.Add(equip.globalId, equip.shotType); } // 세션 관리 정보와 플레이어 ID를 연결. if (m_nodes.ContainsKey(node) == false) { m_nodes.Add(node, equip.globalId); } m_syncFlag = true; // 실제 체크는 checkInitidalEquipment로 매 프레임 한다. }
// public bool Serialize(CharEquipment packet) { bool ret = true; ret &= Serialize(packet.globalId); ret &= Serialize(packet.itemId, CharEquipment.itemNameLength); return(ret); }
// public bool Serialize(CharEquipment packet) { bool ret = true; ret &= Serialize(packet.globalId); ret &= Serialize(packet.shotType); return(ret); }
// public bool Deserialize(ref CharEquipment element) { if (GetDataSize() == 0) { // 데이터가 설정되어있지 않습니다. return(false); } bool ret = true; ret &= Deserialize(ref element.globalId); ret &= Deserialize(ref element.itemId, CharEquipment.itemNameLength); return(ret); }
// public bool Deserialize(ref CharEquipment element) { if (GetDataSize() == 0) { // 데이터가 설정되지 않았다. return(false); } bool ret = true; ret &= Deserialize(ref element.globalId); ret &= Deserialize(ref element.shotType); return(ret); }
// Start is called before the first frame update void Start() { m_strValue = transform.Find("Strength/StrengthValue").GetComponent <Text>(); m_defValue = transform.Find("Defence/DefenceValue").GetComponent <Text>(); m_hpValue = transform.Find("Health/HealthValue").GetComponent <Text>(); m_hpSlider = transform.Find("Health/HealthSlider").GetComponent <Slider>(); m_expValue = transform.Find("Exp/ExpValue").GetComponent <Text>(); m_expSlider = transform.Find("Exp/ExpSlider").GetComponent <Slider>(); m_stateStr = transform.Find("State/Str/StrValue").GetComponent <Text>(); m_stateDef = transform.Find("State/Def/DefValue").GetComponent <Text>(); m_stateCri = transform.Find("State/Cri/CriValue").GetComponent <Text>(); m_player = GameObject.FindGameObjectWithTag("Player"); m_CharEquip = GameObject.Find("Canvas/InvenCanvas").transform.Find("InventoryCanvas/CharEquipment").GetComponent <CharEquipment>(); }
void Start() { speed = 6.0f; gravity = 100.0f; m_distance = 20.0f; m_angleRange = 180f; move = Vector3.zero; m_collider = null; m_animator = GetComponent <Animator>(); m_agent = GetComponent <NavMeshAgent>(); m_controller = GetComponent <CharacterController>(); //////////임시 스텟//////// m_attackRange = 4.0f; /////////////////////////// CharicterStateSet(); GameObject g = GameObject.Find("Canvas/UI/CharacterUI"); if (g != null) { m_charNameText = g.transform.Find("PlayerName/Text").GetComponent <Text>(); m_charLevelText = g.transform.Find("Level/Text").GetComponent <Text>(); m_charHpbar = g.transform.Find("HealthBar").GetComponent <Slider>(); m_expBar = g.transform.Find("Exp").GetComponent <Slider>(); m_charNameText.text = m_charName; } m_CharEquip = GameObject.Find("Canvas").transform.Find("InvenCanvas/InventoryCanvas/CharEquipment").GetComponent <CharEquipment>(); m_health = GetComponent <PlayerHealth>(); m_health.GetHp = m_charOriHp; m_health.Init(); m_camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <MainCamera>(); Transform t = transform.Find("SlashEffect"); if (t != null) { ParticleSystem[] ps = t.GetComponentsInChildren <ParticleSystem>(true); m_particles.AddRange(ps); } t = transform.Find("LevelUpEffect"); if (t != null) { ParticleSystem[] ps = t.GetComponentsInChildren <ParticleSystem>(true); m_levelUpParticles.AddRange(ps); } }
// 매 프레임 호출. public override void execute() { // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크. switch(this.step.do_transition()) { // 무아저씨 등장 데모. case STEP.DEMO0: { if(EventRoot.get().getCurrentEvent() == null) { this.step.set_next(STEP.SELECT_WEAPON); } } break; // 무기 아아템을 선택할 때까지. case STEP.SELECT_WEAPON: { // 무기 아이템을 선택했으면 다음으로 . if(this.player.getShotType() != SHOT_TYPE.EMPTY) { // 선택되지 않은 무기 아이템 삭제. List<ItemController> shot_items = ItemManager.get().findItems(x => x.name.StartsWith("shot")); foreach(var item in shot_items) { ItemManager.get().deleteItem(item.name); } this.select_done_players[this.player.getGlobalIndex()] = true; // 무기 아이템의 스포트 라이트를 지우고 열쇠 위치에 스포트 라이트. this.spotlight_items[0].setPosition(WeaponSelectLevelSequence.getKeyStayPosition().Y(4.0f)); this.spotlight_items[1].SetActive(false); this.step.set_next(STEP.PICKUP_KEY); } } break; // 열쇠를 주을 때까지. case STEP.PICKUP_KEY: { if(ItemManager.get().findItem(this.key_instance_name) == null) { this.spotlight_items[0].SetActive(false); this.step.set_next(STEP.ENTER_DOOR); } } break; // 문으로 들어갈 때까지. case STEP.ENTER_DOOR: { TransportEvent ev = EventRoot.get().getCurrentEvent<TransportEvent>(); if(ev != null) { ev.setEndAtHoleIn(true); this.step.set_next(STEP.TRANSPORT); } } break; // 플로어 이동 이벤트. case STEP.TRANSPORT: { TransportEvent ev = EventRoot.get().getCurrentEvent<TransportEvent>(); if(ev == null) { // 초기 장비의 동기화 대기 쿼리를 발행 . var query = new QuerySelectFinish(this.player.control.getAccountID()); // 쿼리의 타임아웃을 연장. query.timeout = 20.0f; QueryManager.get().registerQuery(query); // 선택한 무기를 게임 서버에 알림. if (this.m_network != null) { CharEquipment equip = new CharEquipment(); equip.globalId = GlobalParam.get().global_account_id; equip.shotType = (int) this.player.getShotType(); Debug.Log("[CLIENT] Send equip AccountID:" + equip.globalId + " ShotType:" + equip.shotType); EquipmentPacket packet = new EquipmentPacket(equip); int serverNode = this.m_network.GetServerNode(); this.m_network.SendReliable<CharEquipment>(serverNode, packet); } else { query.set_done(true); query.set_success(true); } this.step.set_next(STEP.WAIT_FRIEND); } } break; // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { // 던전으로 이동하는 신호 기다림. if(this.select_scene_finish) { // 만약을 위해 선택 완료가 되지 않은 아이콘을 강제로 선택 완료로 표시. // 해버린다. foreach(var icon in this.selecting_icons) { if(icon.step.get_current() == SelectingIcon.STEP.HAI) { continue; } icon.beginHai(); } this.step.set_next_delay(STEP.FINISH, 2.0f); } } break; } // ---------------------------------------------------------------- // // 상태 전환 시 초기화 while(this.step.get_next() != STEP.NONE) { switch(this.step.do_initialize()) { // 무아저씨 등장 데모. case STEP.DEMO0: { EventRoot.get().startEvent<EventWeaponSelect>(); } break; // 열쇠 줍기. case STEP.PICKUP_KEY: { // 플로어 열쇠가 외위에서 떨어진다. this.create_floor_key(); } break; // 문에 들어갈 때까지. case STEP.ENTER_DOOR: { this.spotlight_key.SetActive(true); } break; // 플로어 이동 이벤트. case STEP.TRANSPORT: { this.kabusan.onBeginTransportEvent(); } break; // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { // 다른 플레이어의 상황을 나타내는 아이콘을 표시. foreach(var icon in this.selecting_icons) { icon.setVisible(true); } } break; case STEP.FINISH: { GameRoot.get().setNextScene("GameScene"); } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step.do_execution(Time.deltaTime)) { // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { foreach(var icon in this.selecting_icons) { if(icon.step.get_current() == SelectingIcon.STEP.UUN) { continue; } if(this.select_done_players[icon.player_index]) { icon.beginHai(); } } } break; } // ---------------------------------------------------------------- // this.spotlight_player.setPosition(this.player.control.getPosition().Y(4.0f)); this.spotlight_kabusan.setPosition(this.kabusan.control.getPosition().Y(8.0f)); this.update_queries(); }
void Update() { // 오류 핸들링. NetEventHandling(); // ---------------------------------------------------------------- // // 스텝 내 경과 시간 진행. this.step_timer += Time.deltaTime; // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크한다. if (this.next_step == STEP.NONE) { switch (this.step) { case STEP.WAIT: { } break; } } // ---------------------------------------------------------------- // // 전환 시 초기화. while (this.next_step != STEP.NONE) { this.step = this.next_step; this.next_step = STEP.NONE; switch (this.step) { case STEP.MATCHING: { #if !UNUSE_MATCHING_SERVER int serverNode = -1; if (m_network != null) { serverNode = m_network.Connect(m_serverAddress, NetConfig.MATCHING_SERVER_PORT, Network.ConnectionType.Reliable); if (serverNode >= 0) { GameObject obj = new GameObject("MatchingClient"); m_client = obj.AddComponent <MatchingClient>(); if (m_client == null) { // 오류 강제 전환. m_errorMessage = "매칭을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } m_client.SetServerNode(serverNode); } else { // 오류. m_errorMessage = "매칭 서버에\n접속할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } else { // 오류. m_errorMessage = "통신을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } #else GameObject obj = new GameObject("MatchingClient"); m_client = obj.AddComponent <MatchingClient>(); if (m_client == null) { // 오류로 강제 전환. m_errorMessage = "매칭을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } #endif } break; case STEP.SERVER_START: { m_network.ClearReceiveNotification(); Debug.Log("Launch Listening socket."); // 같은 단말에서 실행할 수 있게 포토 번호를 다르게 한다. // 다른 단말에서 실행할 때는 포트 번호가 같은 것을 사용한다. int port = NetConfig.GAME_PORT + GlobalParam.getInstance().global_account_id; bool ret = m_network.StartServer(port, NetConfig.PLAYER_MAX, Network.ConnectionType.Unreliable); if (m_isHost) { // 게임 서버 시작. int playerNum = m_client.GetMemberNum(); ret &= m_network.StartGameServer(playerNum); } if (ret == false) { // 오류로 강제 전환. m_errorMessage = "게임 통신을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } break; case STEP.SERVER_CONNECT: { // 호스트 이름 획득. if (m_isHost) { string hostname = Dns.GetHostName(); IPAddress[] adrList = Dns.GetHostAddresses(hostname); m_serverAddress = adrList[0].ToString(); } // 게임 서버에 접속. Debug.Log("Connect to GameServer."); int serverNode = m_network.Connect(m_serverAddress, NetConfig.GAME_SERVER_PORT, Network.ConnectionType.Reliable); if (serverNode >= 0) { m_network.SetServerNode(serverNode); } else { // 오류로 강제 전환. m_errorMessage = "게임 서버와 통신할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } break; case STEP.CLIENT_CONNECT: { Debug.Log("Connect to host."); MatchingClient.MemberList[] list = m_client.GetMemberList(); int playerNum = m_client.GetMemberNum(); for (int i = 0; i < playerNum; ++i) { // 같은 단말에서 실행할 때는 전용으로 부여한 플레이어ID로 판별한다. // 다른 단말에서 실행할 때는 IP주소로 판별할 수 있다. // 샘플 코드에서는 양쪽에 대응할 수 있는 플레어ID로 판별한다. if (m_client.GetPlayerId() == i) { // 자기 자신은 접속하지 않는다. continue; } if (list[i] == null) { continue; } // 같은 단말에서 실행할 수 있게 포트 번호를 다르게 한다. // 다른 단말에서 실행할 때는 포트 번호가 같은 것을 사용한다. int port = NetConfig.GAME_PORT + i; string memberAddress = list[i].endPoint.Address.ToString(); int clientNode = m_network.Connect(memberAddress, port, Network.ConnectionType.Unreliable); if (clientNode >= 0) { m_network.SetClientNode(i, clientNode); } else { // 오류로 강제 전환. m_errorMessage = "게임을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } } break; #if UNUSE_MATCHING_SERVER case STEP.WAIT_SYNC: { CharEquipment equip = new CharEquipment(); equip.globalId = GlobalParam.get().global_account_id; equip.shotType = (int)SHOT_TYPE.NEGI; EquipmentPacket packet = new EquipmentPacket(equip); int serverNode = m_network.GetServerNode(); m_network.SendReliable <CharEquipment>(serverNode, packet); } break; #endif case STEP.GAME_START: { GlobalParam.getInstance().fadein_start = true; Application.LoadLevel("WeaponSelectScene"); } break; case STEP.WAIT_RESTART: { if (m_isHost) { m_network.StopGameServer(); } m_network.StopServer(); m_network.Disconnect(); } break; } this.step_timer = 0.0f; } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step) { case STEP.WAIT: { } break; case STEP.MATCHING: { this.next_step = STEP.WAIT_MATCHING; } break; case STEP.WAIT_MATCHING: { #if !UNUSE_MATCHING_SERVER if (m_client != null && m_client.IsFinishedMatching()) { GlobalParam.get().global_account_id = m_client.GetPlayerId(); m_isHost = m_client.IsRoomOwner(); #else { #endif if (m_isHost) { GlobalParam.get().is_host = true; } this.next_step = STEP.SERVER_START; } } break; case STEP.SERVER_START: { // 서버가 시작하길 기다린다. #if UNUSE_MATCHING_SERVER if (this.step_timer > 5.0f) { #else if (this.step_timer > 3.0f) { #endif this.next_step = STEP.SERVER_CONNECT; } } break; case STEP.SERVER_CONNECT: { this.next_step = STEP.CLIENT_CONNECT; } break; case STEP.CLIENT_CONNECT: { #if UNUSE_MATCHING_SERVER this.next_step = STEP.WAIT_SYNC; #else this.next_step = STEP.GAME_START; #endif } break; #if UNUSE_MATCHING_SERVER case STEP.WAIT_SYNC: { // 클라이언트끼리 접속하길 기다린다. // 예제 코드에서는 대기 시간을 넣어서 접속을 기다렸다. // 원래는 UDP로 접속 처리를 작성해 커넥션을 펼 수 있게 하는 편이 좋다 bool isConnected = true; string connect = "Connect:[sync:" + m_syncFlag; for (int i = 0; i < m_client.GetMemberNum(); ++i) { if (i == GlobalParam.get().global_account_id) { continue; } int node = m_network.GetClientNode(i); isConnected &= m_network.IsConnected(node); connect += "[" + i + "(" + node + "):" + m_network.IsConnected(node) + "] "; } //Debug.Log(connect); if (isConnected || this.step_timer > 10.0f) { this.next_step = STEP.GAME_START; } ++count_; } break; #endif case STEP.GAME_START: { } break; case STEP.ERROR: { this.next_step = STEP.WAIT_RESTART; } break; case STEP.WAIT_RESTART: { } break; } // ---------------------------------------------------------------- // }
// 매 프레임 호출. public override void execute() { // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크. switch (this.step.do_transition()) { // 무아저씨 등장 데모. case STEP.DEMO0: { if (EventRoot.get().getCurrentEvent() == null) { this.step.set_next(STEP.SELECT_WEAPON); } } break; // 무기 아아템을 선택할 때까지. case STEP.SELECT_WEAPON: { // 무기 아이템을 선택했으면 다음으로 . if (this.player.getShotType() != SHOT_TYPE.EMPTY) { // 선택되지 않은 무기 아이템 삭제. List <ItemController> shot_items = ItemManager.get().findItems(x => x.name.StartsWith("shot")); foreach (var item in shot_items) { ItemManager.get().deleteItem(item.name); } this.select_done_players[this.player.getGlobalIndex()] = true; // 무기 아이템의 스포트 라이트를 지우고 열쇠 위치에 스포트 라이트. this.spotlight_items[0].setPosition(WeaponSelectLevelSequence.getKeyStayPosition().Y(4.0f)); this.spotlight_items[1].SetActive(false); this.step.set_next(STEP.PICKUP_KEY); } } break; // 열쇠를 주을 때까지. case STEP.PICKUP_KEY: { if (ItemManager.get().findItem(this.key_instance_name) == null) { this.spotlight_items[0].SetActive(false); this.step.set_next(STEP.ENTER_DOOR); } } break; // 문으로 들어갈 때까지. case STEP.ENTER_DOOR: { TransportEvent ev = EventRoot.get().getCurrentEvent <TransportEvent>(); if (ev != null) { ev.setEndAtHoleIn(true); this.step.set_next(STEP.TRANSPORT); } } break; // 플로어 이동 이벤트. case STEP.TRANSPORT: { TransportEvent ev = EventRoot.get().getCurrentEvent <TransportEvent>(); if (ev == null) { // 초기 장비의 동기화 대기 쿼리를 발행 . var query = new QuerySelectFinish(this.player.control.getAccountID()); // 쿼리의 타임아웃을 연장. query.timeout = 20.0f; QueryManager.get().registerQuery(query); // 선택한 무기를 게임 서버에 알림. if (this.m_network != null) { CharEquipment equip = new CharEquipment(); equip.globalId = GlobalParam.get().global_account_id; equip.shotType = (int)this.player.getShotType(); Debug.Log("[CLIENT] Send equip AccountID:" + equip.globalId + " ShotType:" + equip.shotType); EquipmentPacket packet = new EquipmentPacket(equip); int serverNode = this.m_network.GetServerNode(); this.m_network.SendReliable <CharEquipment>(serverNode, packet); } else { query.set_done(true); query.set_success(true); } this.step.set_next(STEP.WAIT_FRIEND); } } break; // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { // 던전으로 이동하는 신호 기다림. if (this.select_scene_finish) { // 만약을 위해 선택 완료가 되지 않은 아이콘을 강제로 선택 완료로 표시. // 해버린다. foreach (var icon in this.selecting_icons) { if (icon.step.get_current() == SelectingIcon.STEP.HAI) { continue; } icon.beginHai(); } this.step.set_next_delay(STEP.FINISH, 2.0f); } } break; } // ---------------------------------------------------------------- // // 상태 전환 시 초기화 while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // 무아저씨 등장 데모. case STEP.DEMO0: { EventRoot.get().startEvent <EventWeaponSelect>(); } break; // 열쇠 줍기. case STEP.PICKUP_KEY: { // 플로어 열쇠가 외위에서 떨어진다. this.create_floor_key(); } break; // 문에 들어갈 때까지. case STEP.ENTER_DOOR: { this.spotlight_key.SetActive(true); } break; // 플로어 이동 이벤트. case STEP.TRANSPORT: { this.kabusan.onBeginTransportEvent(); } break; // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { // 다른 플레이어의 상황을 나타내는 아이콘을 표시. foreach (var icon in this.selecting_icons) { icon.setVisible(true); } } break; case STEP.FINISH: { GameRoot.get().setNextScene("GameScene"); } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { // 다른 플레이어 기다림. case STEP.WAIT_FRIEND: { foreach (var icon in this.selecting_icons) { if (icon.step.get_current() == SelectingIcon.STEP.UUN) { continue; } if (this.select_done_players[icon.player_index]) { icon.beginHai(); } } } break; } // ---------------------------------------------------------------- // this.spotlight_player.setPosition(this.player.control.getPosition().Y(4.0f)); this.spotlight_kabusan.setPosition(this.kabusan.control.getPosition().Y(8.0f)); this.update_queries(); }
void Update() { // 오류 핸들링. NetEventHandling(); // ---------------------------------------------------------------- // // 스텝 내 경과 시간 진행. this.step_timer += Time.deltaTime; // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크한다. if(this.next_step == STEP.NONE) { switch(this.step) { case STEP.WAIT: { } break; } } // ---------------------------------------------------------------- // // 전환 시 초기화. while(this.next_step != STEP.NONE) { this.step = this.next_step; this.next_step = STEP.NONE; switch(this.step) { case STEP.MATCHING: { #if !UNUSE_MATCHING_SERVER int serverNode = -1; if (m_network != null) { serverNode = m_network.Connect(m_serverAddress, NetConfig.MATCHING_SERVER_PORT, Network.ConnectionType.Reliable); if (serverNode >= 0) { GameObject obj = new GameObject("MatchingClient"); m_client = obj.AddComponent<MatchingClient>(); if (m_client == null) { // 오류 강제 전환. m_errorMessage = "매칭을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } m_client.SetServerNode(serverNode); } else { // 오류. m_errorMessage = "매칭 서버에\n접속할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } else { // 오류. m_errorMessage = "통신을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } #else GameObject obj = new GameObject("MatchingClient"); m_client = obj.AddComponent<MatchingClient>(); if (m_client == null) { // 오류로 강제 전환. m_errorMessage = "매칭을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } #endif } break; case STEP.SERVER_START: { m_network.ClearReceiveNotification(); Debug.Log("Launch Listening socket."); // 같은 단말에서 실행할 수 있게 포토 번호를 다르게 한다. // 다른 단말에서 실행할 때는 포트 번호가 같은 것을 사용한다. int port = NetConfig.GAME_PORT + GlobalParam.getInstance().global_account_id; bool ret = m_network.StartServer(port, NetConfig.PLAYER_MAX, Network.ConnectionType.Unreliable); if (m_isHost) { // 게임 서버 시작. int playerNum = m_client.GetMemberNum(); ret &= m_network.StartGameServer(playerNum); } if (ret == false) { // 오류로 강제 전환. m_errorMessage = "게임 통신을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } break; case STEP.SERVER_CONNECT: { // 호스트 이름 획득. if (m_isHost) { string hostname = Dns.GetHostName(); IPAddress[] adrList = Dns.GetHostAddresses(hostname); m_serverAddress = adrList[0].ToString(); } // 게임 서버에 접속. Debug.Log("Connect to GameServer."); int serverNode = m_network.Connect(m_serverAddress, NetConfig.GAME_SERVER_PORT, Network.ConnectionType.Reliable); if (serverNode >= 0) { m_network.SetServerNode(serverNode); } else { // 오류로 강제 전환. m_errorMessage = "게임 서버와 통신할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } break; case STEP.CLIENT_CONNECT: { Debug.Log("Connect to host."); MatchingClient.MemberList[] list = m_client.GetMemberList(); int playerNum = m_client.GetMemberNum(); for (int i = 0; i < playerNum; ++i) { // 같은 단말에서 실행할 때는 전용으로 부여한 플레이어ID로 판별한다. // 다른 단말에서 실행할 때는 IP주소로 판별할 수 있다. // 샘플 코드에서는 양쪽에 대응할 수 있는 플레어ID로 판별한다. if (m_client.GetPlayerId() == i) { // 자기 자신은 접속하지 않는다. continue; } if (list[i] == null) { continue; } // 같은 단말에서 실행할 수 있게 포트 번호를 다르게 한다. // 다른 단말에서 실행할 때는 포트 번호가 같은 것을 사용한다. int port = NetConfig.GAME_PORT + i; string memberAddress = list[i].endPoint.Address.ToString(); int clientNode = m_network.Connect(memberAddress, port, Network.ConnectionType.Unreliable); if (clientNode >= 0) { m_network.SetClientNode(i, clientNode); } else { // 오류로 강제 전환. m_errorMessage = "게임을 시작할 수 없습니다.\n\n버튼을 누르세요."; this.step = STEP.ERROR; } } } break; #if UNUSE_MATCHING_SERVER case STEP.WAIT_SYNC: { CharEquipment equip = new CharEquipment(); equip.globalId = GlobalParam.get().global_account_id; equip.shotType = (int)SHOT_TYPE.NEGI; EquipmentPacket packet = new EquipmentPacket(equip); int serverNode = m_network.GetServerNode(); m_network.SendReliable<CharEquipment>(serverNode, packet); } break; #endif case STEP.GAME_START: { GlobalParam.getInstance().fadein_start = true; Application.LoadLevel("WeaponSelectScene"); } break; case STEP.WAIT_RESTART: { if (m_isHost) { m_network.StopGameServer(); } m_network.StopServer(); m_network.Disconnect(); } break; } this.step_timer = 0.0f; } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step) { case STEP.WAIT: { } break; case STEP.MATCHING: { this.next_step = STEP.WAIT_MATCHING; } break; case STEP.WAIT_MATCHING: { #if !UNUSE_MATCHING_SERVER if (m_client != null && m_client.IsFinishedMatching()) { GlobalParam.get().global_account_id = m_client.GetPlayerId(); m_isHost = m_client.IsRoomOwner(); #else { #endif if (m_isHost) { GlobalParam.get().is_host = true; } this.next_step = STEP.SERVER_START; } } break; case STEP.SERVER_START: { // 서버가 시작하길 기다린다. #if UNUSE_MATCHING_SERVER if (this.step_timer > 5.0f){ #else if (this.step_timer > 3.0f){ #endif this.next_step = STEP.SERVER_CONNECT; } } break; case STEP.SERVER_CONNECT: { this.next_step = STEP.CLIENT_CONNECT; } break; case STEP.CLIENT_CONNECT: { #if UNUSE_MATCHING_SERVER this.next_step = STEP.WAIT_SYNC; #else this.next_step = STEP.GAME_START; #endif } break; #if UNUSE_MATCHING_SERVER case STEP.WAIT_SYNC: { // 클라이언트끼리 접속하길 기다린다. // 예제 코드에서는 대기 시간을 넣어서 접속을 기다렸다. // 원래는 UDP로 접속 처리를 작성해 커넥션을 펼 수 있게 하는 편이 좋다 bool isConnected = true; string connect = "Connect:[sync:" + m_syncFlag; for (int i = 0; i < m_client.GetMemberNum(); ++i) { if (i == GlobalParam.get().global_account_id) { continue; } int node = m_network.GetClientNode(i); isConnected &= m_network.IsConnected(node); connect += "[" + i +"(" + node + "):" + m_network.IsConnected(node) + "] "; } //Debug.Log(connect); if (isConnected || this.step_timer > 10.0f) { this.next_step = STEP.GAME_START; } ++count_; } break; #endif case STEP.GAME_START: { } break; case STEP.ERROR: { this.next_step = STEP.WAIT_RESTART; } break; case STEP.WAIT_RESTART: { } break; } // ---------------------------------------------------------------- // }