Puzzle Platform(multiplay)

정재훈·2023년 5월 23일
0

Unreal Multiplay

목록 보기
1/7

server

C:\Users\rituy>"C:\Program Files\Epic Games\UE_5.1\Engine\Binaries\Win64\UnrealEditor.exe" "D:\UnrealProjects\MultiPlayer\MultiPlayer.uproject" /Game/ThirdPerson/Maps/ThirdPersonMap -server -log

(unreal edior 경로) (project 경로) (Map 경로 생략가능) -server -log

client

C:\Users\rituy>"C:\Program Files\Epic Games\UE_5.1\Engine\Binaries\Win64\UnrealEditor.exe" "D:\UnrealProjects\MultiPlayer\MultiPlayer.uproject" 192.168.0.10 -game -log

(unreal edior 경로) (project 경로) (Server IP 주소) -gmae -log

Server에서만 코드실행

if (HasAuthority()) {
	.
	.
	.
}

HasAuthority() = true //Server
HasAuthority() = false //Client

Authority Replicates

Server만 Authority를 가질수 있으며 Server가 항상 옳다고 가정한다.

if (HasAuthority()) {
		SetReplicates(true);
		SetReplicateMovement(true);
	}

Replicate를 통해 server의 값을 client에 복제할수 있다.
반대의 경우는 불가능하다.

두 vector 사이를 왕복하는 Platform

UPROPERTY(EditAnywhere, Meta = (MakeEditWidget = true))
		FVector TargetLocation;

unreal editor widget에서 targetLocation을 수정할수있게 UPROPERTY 설정

void AMovingPlatform::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (HasAuthority()) {
		FVector Location = GetActorLocation();
		//TargetLocation까지의 거리
		float JournyLength = (GlobalTargetLocation - GlobalStartLocation).Size();
		//현재 이동한 거리
		float JourneyTraveled = (Location - GlobalStartLocation).Size();
		
		//TargetLocation까지 도착했을경우 swap
		if (JournyLength <= JourneyTraveled) {
			FVector Swap = GlobalStartLocation;
			GlobalStartLocation = GlobalTargetLocation;
			GlobalTargetLocation = Swap;
		}
		//방향vector 정규화
		FVector Direction = (GlobalTargetLocation - GlobalStartLocation).GetSafeNormal();
		//targetLocation으로 이동
		Location += Speed * DeltaTime*Direction;

		SetActorLocation(Location);
	}
}

PlatformTrigger

PlatformTrigger.cpp

void APlatformTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	for (AMovingPlatform* Platform : PlatformsToTrigger)
	{
		Platform->AddActiveTrigger();
	}
}

void APlatformTrigger::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	for (AMovingPlatform* Platform : PlatformsToTrigger)
	{
		Platform->RemoveActiveTrigger();
	}
}

오버랩 이벤트를 통해 트리거 박스 위에 캐릭터가 있을경우 플랫폼이 움직입니다.

if (ActiveTriggers > 0) {
	//위에 tick함수의 플랫폼 움직이는 코드
}

void AMovingPlatform::AddActiveTrigger()
{
	ActiveTriggers++;
}

void AMovingPlatform::RemoveActiveTrigger()
{
	if (ActiveTriggers > 0)
	{
		ActiveTriggers--;
	}
}

hosting joining

커맨드 프롬프트가 아닌 게임내 콘솔에서 간단한 명령어로 게임을 호스팅하고 client가 join할수 있습니다.

PuzzlePlatformGameInstance.h

UFUNCTION(Exec)
		void Host();

UFUNCTION(Exec)
		void Join(const FString& Address);

UFUNCTION(Exec)를 사용하면 게임콘솔에서 함수를 명령어로 사용가능

PuzzlePlatformGameInstance.cpp

void UPuzzlePlatformGameInstance::Host()
{
	UEngine* Engine = GetEngine();
	if (!ensure(Engine != nullptr)) return;

	Engine->AddOnScreenDebugMessage(0, 2, FColor::Green, TEXT("Hosting"));
	UWorld* World = GetWorld();
	if (!ensure(World != nullptr)) return;

	World->ServerTravel("/Game/ThirdPerson/Maps/ThirdPersonMap?listen");
}

void UPuzzlePlatformGameInstance::Join(const FString& Address)
{
	UEngine* Engine = GetEngine();
	if (!ensure(Engine != nullptr)) return;

	Engine->AddOnScreenDebugMessage(0, 5, FColor::Green, FString::Printf(TEXT("Joining %s"), *Address));
	APlayerController* PlayerController = GetFirstLocalPlayerController();
	if (!ensure(PlayerController != nullptr)) return;

	PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);
}

Test

  • 두개의 게임 실행
    C:\Users\rituy>"C:\Program Files\Epic Games\UE_5.1\Engine\Binaries\Win64\UnrealEditor.exe" "D:\UnrealProjects\MultiPlayer\MultiPlayer.uproject" -game -log

  • 게임1 콘솔명령어
    Host

  • 게임2 콘솔 명령어
    Join 192.168.0.10

profile
게임 개발 공부중!

0개의 댓글