반응형

전에 작업한 부분이 게임에 입장하는 패킷을 보내는 부분이었다.

그리고 정상적으로 패킷을 수신하는 것도 확인했다.

이제 패킷을 수신하고 플레이어를 스폰해주는 코드를 언리얼에 작성해주자.


UMyGameInstance.h 수정

 

void UMyGameInstance::HandleSpawn(const Protocol::PlayerInfo& PlayerInfo)
{
	if (Socket == nullptr || GameServerSession == nullptr)
		return;

	auto* World = GetWorld();
	if (World == nullptr)
		return;

	// 중복 처리 체크
	const uint64 ObjectId = PlayerInfo.object_id();
	if (Players.Find(ObjectId) != nullptr)
		return;

	FVector SpawnLocation(PlayerInfo.x(), PlayerInfo.y(), PlayerInfo.z());
	FRotator SpawnRotation(0, PlayerInfo.yaw(), 0);
	AActor* Actor = World->SpawnActor(PlayerClass, &SpawnLocation, &SpawnRotation);

	Players.Add(PlayerInfo.object_id(), Actor);
}

void UMyGameInstance::HandleSpawn(const Protocol::S_ENTER_GAME& EnterGamePkt)
{
	HandleSpawn(EnterGamePkt.players());
}

void UMyGameInstance::HandleSpawn(const Protocol::S_SPAWN& SpawnPkt)
{
	for (auto& Player : SpawnPkt.players())
	{
		HandleSpawn(Player);
	}
}

 

 

이렇게 입장 패킷을 보내면 플레이어 캐릭터가 생성되는 것을 확인 할 수 있다.


이제 A라는 플레이어가 입장했다는 정보를 주고받는것 까지는 잘 되었다.

이제 이미 들어와 있던 다른 플레어들(B,C....)에게도 A가 들어왔다는 정보를 줘야 한다.

 

서버의 Room.cpp코드에서 HandleEnterPlayerLocked 함수에 아래와 같이 코드를 추가해주자.

	//입장 사실을 다른 플레이어에게 알린다
	{
		Protocol::S_SPAWN spawnPkt;

		Protocol::PlayerInfo* playerInfo = spawnPkt.add_players();
		playerInfo->CopyFrom(*player->playerInfo);

		SendBufferRef sendBuffer = ClientPacketHandler::MakeSendBuffer(spawnPkt);
		Broadcast(sendBuffer, player->playerInfo->object_id());
	}

 

지금 상태로 클라이언트를 3개 실행시키면, 아래처럼 3개의 플레이어가 잘 스폰되는 것 처럼 보이지만 다른 클라이언트 화면에서 보면 플레이어가 제대로 생성되지 않은걸 볼 수 있다.

접속한 순서

 

 

 

이런 문제가 발생하는 이유는 기존에 이미 접속해있던 플레이어들의 정보를 전송해주지 않아서 발생한 문제이다.

문제를 해결하기 위해 서버의 Room 코드를 수정해주자.


Room.h 코드 수정

#pragma once

class Room : public enable_shared_from_this<Room>
{

private:
	void Broadcast(SendBufferRef sendBuffer, uint64 exceptId = 0);

};

 

	//기존 입장한 플레이어 목록을 신입 플레이어한테 전송해준다
	{
		Protocol::S_SPAWN spawnPkt;

		for (auto& item : _players)
		{
			Protocol::PlayerInfo* playerInfo = spawnPkt.add_players();
			playerInfo->CopyFrom(*item.second->playerInfo);
		}

		SendBufferRef sendBuffer = ClientPacketHandler::MakeSendBuffer(spawnPkt);
		if (auto session = player->session.lock())
			session->Send(sendBuffer);
	}

 

 

이제 정상적으로 접속한 인원수대로 플레이어가 생성되는 것을 확인할 수 있다.

반응형

'언리얼 엔진 서버 연동' 카테고리의 다른 글

플레이어 구분  (0) 2024.04.08
Despawn  (0) 2024.04.08
Spawn(1)  (1) 2024.04.07
protobuf  (0) 2024.04.06
패킷 작업(Protobuf)  (0) 2024.04.06