Study/TIL(Today I Learned)

24.10.23 VV

에린_1 2024. 10. 23. 23:57
728x90

24.10.23 VV

VV

서버와의 연결

간단한 로그인 UI를 만들었고, 이번에는 C++서버와의 연결을 준비했다. C++ 서버의 경우 최흥배님의 깃헙을 참조해 사용했다.

NetworkManager

  • NetworkManager
    • MyGameInstance에서 다 해결해주는 것이 아니라, 서버와의 연결을 담당해줄 클래스를 만들어 주었다.
      • NetworkManager.h
      //NetworkManager.h
      UCLASS()
      class VERSUSVILLAGE_API UNetworkManager : public UObject
      {
      	GENERATED_BODY()
      	
      public:
      	bool ConnectToServer(FString ServerAddress, int32 Port);
      	void SendData(FString DataToSend);
      
      private:
      	class FSocket* ClientSocket;
      };
      
      • NetworkManager.cpp
      //NetworkManager.cpp
      // Fill out your copyright notice in the Description page of Project Settings.
      
      #include "NetworkManager.h"
      #include "Networking/Public/Networking.h"
      #include "Sockets.h"
      #include "SocketSubsystem.h"
      #include "Interfaces/IPv4/IPv4Address.h"
      
      bool UNetworkManager::ConnectToServer(FString ServerAddress, int32 Port)
      {
      	FIPv4Address Ip;
      	FIPv4Address::Parse(ServerAddress, Ip);
      
      	TSharedRef<FInternetAddr> Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
      	Addr->SetIp(Ip.Value);
      	Addr->SetPort(Port);
      
      	ClientSocket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("Default"), false);
      	if (ClientSocket->Connect(*Addr))
      	{
      		UE_LOG(LogTemp, Log, TEXT("Succ ConnectToServer"));
      		return true;
      	}
      	else
      	{
      		UE_LOG(LogTemp, Log, TEXT("Fail ConnectToServer"));
      		return false;
      	}
      
      }
      
      void UNetworkManager::SendData(FString DataToSend)
      {
      	if (ClientSocket)
      	{
      		TCHAR* SerializedChar = DataToSend.GetCharArray().GetData();
      		int32 Size = FCString::Strlen(SerializedChar);
      		int32 Sent = 0;
      
      		ClientSocket->Send((uint8*)TCHAR_TO_UTF8(SerializedChar), Size, Sent);
      		UE_LOG(LogTemp, Log, TEXT("Succ SendData"));
      	}
      }
      
    • 여러 트러블 슈팅을 겪었지만 성공적으로 서버와의 연결을 성공 할 수 있었다.
  • 아오.. 되게 한게 없이 짧지만 트러블 슈팅 때문에 너무 많은 시간을 잡아 먹었다.. 쉽지않아 쉽지않아

트러블 슈팅

MSB3073 에러

  1. MSB3073에러가 발생해서 빌드가 안되는 문제를 겪었다.
  2. VS를 다시 켜보거나 Binaries를 삭제하고 리빌드 하는 과정을 거쳤지만 문제가 해결되지 않았다.
  3. 해결 방법
    1. Build.cs 파일 수정
      • FSocket 및 네트워킹 관련 기능을 사용하기 위해서는 프로젝트의 .Build.cs 파일에 필요한 모듈을 추가해야 했다.
    2. 프로젝트 폴더에서 .Build.cs 파일을 열어서 PublicDependencyModuleNames에 필요한 모듈을 추가해주었다.
      • 나는 Sockets 와 Networking 모듈이 필요했기에 추가해주었다.
    3. PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Sockets", "Networking" });
    4. 성공적으로 빌드할 수 있었다.

NewObject with empty name can't be used to create default subobjects 에러

  1. NewObject 를 객체 생성할 때 발생하는 제한 사항과 관련된 문제였다. 언리얼 엔진에서 NewObject 를 사용하여 객체를 생성하는 경우, 특히 UObject 를 상속받은 클래스의 생성자 내부에서 사용할 때, 이름 충돌 문제나 기본 서브오브젝트 생성 규칙과 관련된 오류가 발생할 수 있었다.
  2. 해결 방법
    1. 생성자 외부에서 NewObject를 사용하는 방법을 사용했다.
    2. NewObject<> 는 생성자 외부에서 호출하면 문제가 발생하지 않기 때문에, 생성자 대신 다른 메서드에서 객체를 생성하는 방법을 사용했다.
    3. void UMyGameInstance::Init()
      {
      	Super::Init();
      	InitializeNetworkManager();
      	//Try Connect TO Server
      	NetworkManager->ConnectToServer("127.0.0.1", 7777);
      }
      
      void UMyGameInstance::InitializeNetworkManager()
      {
      	//Create NetworkManager Instance
      	NetworkManager = NewObject<UNetworkManager>(this, UNetworkManager::StaticClass());
      }
728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.10.29 VV, UE5, DB  (0) 2024.10.29
24.10.28 VV  (0) 2024.10.29
24.10.22 VV, UE5  (3) 2024.10.23
24.10.21 UE5  (0) 2024.10.22
24.10.18 UE5  (0) 2024.10.18